搭建spring环境
1.导入jar包(5+1个)(IDEA可以直接创建spring项目)
spring-aop.jar //开发aop
spring-beans.jar //处理Bean
spring-context.jar //处理spring上下文
spring-core.jar //核心jar
spring-expression.jar //spring表达式 EL JTSL
commons-logging.jar //日志
2.编写配置文件applicationContext.xml
普通版
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:cache="http://www.springframework.org/schema/cache" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
</beans>
事务版
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:cache="http://www.springframework.org/schema/cache" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
</beans>
依赖注入
set方法赋值
用<property>标签
如果是简单类型(8个基本+String),标签内用value(value=“属性值”,属性值类型默认为String类型)
如果是对象类型,标签内用ref=“需要引用的id值”,实现对象与对象之间的依赖关系
构造方法赋值
用<constructor-arg>标签
默认会按照构造方法属性顺序赋值,也可用name指定参数名、index指定索引位置、type指定参数类型
如果是简单类型(8个基本+String),标签内用value
如果是对象类型,标签内用ref=“需要引用的id值”,实现对象与对象之间的依赖关系
p命名空间赋值
引入p命名空间
xmlns:p="http://www.springframework.org/schema/p"
简单类型: p:属性名=“属性值”
引用类型:p:属性名-ref=“引用的id”
自动装配(只适用于ref类型)
<bean id="student" class="cn.test.entity.Student" autowire="byName|byType|constructor"/>
byName:自动寻找:其他bean的id值=该Student类的属性名
byType :其他bean的类型(class) 是否与 该Student类的ref属性类型一致
constructor:其他bean的类型(class)是否与该Course类的构造方法参数的类型一致
自动装配虽然可以减少代码量,但是会降低程序的可读性, 使用时需要谨慎
使用注解定义bean
通过注解的形式 将bean以及相应的属性值 放入ioc容器
步骤:
a.在相应的java文件添加注解
@Component细化:
dao层注解:@Repository
service层注解:@Service
控制层注解:@Controller
b.在applicationContext.xml中添加扫描器
<context:component-scan base-package="cn.test.dao"/>
使用注解实现事务
1.导入jar包
spring-tx.jar
ojbdc.jar
commons-dbcp.jar 连接池使用到数据源
commons-pool.jar 连接池
spring-jdbc.jar
aopalliance.jar
2.在applicationContext.xml中配置
<!-- 配置注解扫描器 -->
<context:component-scan base-package="cn.test.daoImpl"/>
<!-- 配置数据库相关 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring"/>
<property name="username" value="root"/>
<property name="password" value="qiuqiuqiu"/>
</bean>
<!-- 配置事务管理器txManager -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 增加对事务的支持 -->
<tx:annotation-driven transaction-manager="txManager"/>
3.使用
在需要 成为事务的的方法 前加注解@Transactional
AOP切面编程
一个普通类 → 由特定功能的类四种方法:
a.继承类
b.实现接口(类 → 通知 通过实现接口)
c.注解
d.配置
前置通知
实现步骤:
a.导入jar包(aopalliance.jar、aspectjweaver.jar)
b.编写业务类、业务方法和通知类(前置通知类需实现MethodBeforeAdvice接口)
c.配置
将业务类、通知 纳入springIOC容器
定义切入点、定义通知类(另一端), 通过pointcut-ref将两端连起来
<!-- 配置前置通知 -->
<!-- 目标方法addStudent() -->
<bean id="studentSerice" class="cn.test.serviceImpl.StudentServiceImpl">
<property name="studentDao" ref="studentDao"/>
</bean>
<!-- 前置通知类 -->
<bean id="logBefore" class="cn.test.aop.LogBefore">
</bean>
<!-- 将方法所在类和通知关联 -->
<aop:config>
<!-- 配置切入点(在哪里执行通知) -->
<aop:pointcut expression="execution(public * cn.test.service.StudentService..*(..))" id="pointCut"/>
<!--相当于 连结切入点 和 切面 的线-->
<aop:advisor advice-ref="logBefore" pointcut-ref="pointCut"/>
</aop:config>
后置通知
与前置通知类似,后置通知类实现MethodBeforeAdvice接口
异常通知
需实现ThrowsAdvice接口,看源码发现该接口虽然为空接口,但要实现
public void afterThrowing([Method, args, target], ThrowableSubclass)方法
两种实现:
a.public void afterThrowing(Method, args, target, ThrowableSubclass)
b.public void afterThrowing(ThrowableSubclass)
环绕通知
在目标方法的前后、异常发生时、最终等各个地方都可以进行的通知,最强大的一个通知;可以获取目标方法的全部控制权
在使用环绕通知时,目标方法的一切信息都可以通过invocation参数获取
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = null;
try{
System.out.println("用环绕通知实现的 前置通知");
//执行目标方法(该代码前的代码为前置通知, 后面的代码为后置通知)
result = invocation.proceed();
System.out.print("用环绕通知实现的 后置通知: 目标对象:"+invocation.getThis()+" 方法名:"+invocation.getMethod());
System.out.println(" 方法个数参数:"+invocation.getArguments().length+" 方法返回值:"+result);
}catch (Exception e){
//catch里的代码为异常通知
System.out.println("用环绕通知实现的 异常通知");
}
return result;
}
用注解实现通知
a.导入jar包(aopalliance.jar、aspectjweaver.jar)
b.编写业务类、业务方法和通知类
c.配置
将业务类、通知 纳入springIOC容器(注解形式实现aop时,通知方法参数列表不能乱写)
@Component("logAnnotation")//用注解方式将通知纳入springIOC容器
@Aspect//此类是一个通知
public class LogAspectAnnotation {
//前置通知
@Before("execution(public * cn.test.service.StudentService..*(..)))")//属性:定义切点
public void myBefore(JoinPoint joinPoint){
System.out.println("注解形式 前置通知: 目标对象:"+joinPoint.getTarget()+" 方法:"+joinPoint.getSignature().getName()+" 参数列表:"+ Arrays.toString(joinPoint.getArgs()));
}
//后置通知
@AfterReturning(pointcut = "execution(public * cn.test.service.StudentService..*(..)))" , returning = "returningValue")
public void myAfter(JoinPoint joinPoint, Object returningValue){
System.out.println("注解形式 后置通知: 目标对象:"+joinPoint.getTarget()+" 方法:"+joinPoint.getSignature().getName()+" 参数列表:"+ Arrays.toString(joinPoint.getArgs())+" 返回值:"+returningValue);
}
//环绕通知
@Around("execution(public * cn.test.service.StudentService..*(..)))")
public void myArround(ProceedingJoinPoint pj){
//方法执行前 前置通知
System.out.println("注解形式 环绕通知 前置通知");
try {
//方法执行时
pj.proceed();
//方法执行后 后置通知
System.out.println("注解形式 环绕通知 后置通知");
}catch (Throwable throwable) {
//发生异常时 异常通知
System.out.println("注解形式 环绕通知 异常通知");
throwable.printStackTrace();
} finally {
//最终通知
System.out.println("注解形式 环绕通知 最终通知");
}
}
//异常通知
@AfterThrowing(pointcut = "execution(public * cn.test.service.StudentService..*(..)))", throwing = "e")
public void myThrowing(JoinPoint jp, NullPointerException e){
System.out.println("注解形式 异常通知 :"+ e);
}
//最终通知
@After("execution(public * cn.test.service.StudentService..*(..)))")
public void myAfter(){
System.out.println("最终通知");
}
}
在applicationContext.xml中开启注解对AOP的支持、配置注解扫描器
扫描器会将指定包中的@Componet、@Service、@Respository、@Controller修饰的类产生的对象增加到IOC容器中(注意扫描器只管这四种)
<!-- 配置注解扫描器 -->
<context:component-scan base-package="cn.test.daoImpl, cn.test.aop"/>
<!--开启注解对AOP支持-->
<aop:aspectj-autoproxy/>
通过配置实现通知
基于Schema配置
类似于实现接口的方式,但不需要继承接口,而是通过配置
applicationContext.xml:
<!-- 目标方法addStudent() -->
<bean id="studentSerice" class="cn.test.serviceImpl.StudentServiceImpl">
<property name="studentDao" ref="studentDao"/>
</bean>
<!-- 将通知导入IOC容器 -->
<bean id="logArroundSchema" class="cn.test.aop.LogArroundSchema"/>
<!-- 将方法所在类和通知关联 -->
<aop:config>
<aop:pointcut id="logSchema" expression="execution(public * addStudent(..))"/>
<aop:aspect ref="logArroundSchema">
<aop:around method="invoke" pointcut-ref="logSchema"/>
</aop:aspect>
</aop:config>
LogArroundSchema.java:
public class LogArroundSchema {
public Object invoke(ProceedingJoinPoint invocation) throws Throwable {
Object result = null;
try{
System.out.println("【配置形式】用环绕通知实现的 前置通知");
//执行目标方法(该代码前的代码为前置通知, 后面的代码为后置通知)
result = invocation.proceed() ;
System.out.print("【配置形式】用环绕通知实现的 后置通知: 目标对象:"+invocation.getThis()+" 方法名:"+invocation.getSignature().getName());
System.out.println(" 方法个数参数:"+invocation.getArgs().length+" 方法返回值:"+result);
}catch (Exception e){
//catch里的代码为异常通知
System.out.println("【配置形式】用环绕通知实现的 异常通知"+e);
e.printStackTrace();
}
return result;
}
}
Spring开发Web项目
在web.xml中配置web启动时自动实例化IOC容器(需导入spring-web.jar)
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<!--
配置spring-web.jar提供的监听器,此监听器可以在服务器启动时初始化IOC容器
初始化IOC容器(applicationContext.xml):
1.告诉监听器此容器的位置context-para(在上面)
2.约定放在WEB-INF里并且文件名必须叫applicationContext.xml
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
拆分Spring配置文件
拆分方式
a.三层结构
UI(html/css/jsp、Servlet) applicationContext-Controller.xml
Service applicationContext-Service.xml
Dao applicationContext-Dao.xml
公共部分(例数据库:applicationContext-DB.xml)
b.功能拆分
学生相关配置 applicationContext-Student.xml
班级相关配置 applicationContext-Class.xml
合并配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:applicationContext-*.xml
</param-value>
</context-param>