1:概念
连接点:joinpoint
切入点:pointcut
增强:advice
目标对象:target
织入 wave
代理 proxy
切面 aspect
需要导入依赖:spring-aspect
基于注解的AOP配置
在springxml配置
<!--开启Spring注解扫描--> <context:component-scan base-package="com.qf"/>
四种基本通知,和环绕通知
public class MyAdvice { //通知增强类
//前置通知方法
public void before(){
System.out.println("在调用目标方法之前执行....(前置通知)");
}
//异常通知方法
public void afterThrowing(){
System.out.println("在调用目标方法出现后执行(报错)....(异常通知)");
}
//后置通知方法
public void afterReturning(){
System.out.println("在调用目标方法之后执行(不报错)....(后置通知)");
}
//最终通知方法
public void after(){
System.out.println("在调用目标方法后执行(无论是否报错)....(最终通知)");
}
//环绕通知
public Object around(ProceedingJoinPoint point){
try {
System.out.println("在调用目标方法之前执行....(前置通知)");
//调用目标对象的目标方法
Object proceed = point.proceed();
Object target = point.getTarget();
System.out.println("获取到目标对象的类"+target);
Signature signature = point.getSignature();
System.out.println("获取目标对象的方法"+signature);
System.out.println("在调用目标方法之后执行(不报错)....(后置通知)");
return proceed;
} catch (Throwable throwable) {
//throwable.printStackTrace();
System.out.println("在调用目标方法出现后执行(报错)....(异常通知)");
System.out.println(throwable);
}finally {
System.out.println("在调用目标方法后执行(无论是否报错)....(最终通知)");
}
return null;
将通知类注入ioc容器
<bean id="advice" class="com.zdq.advice.MyAdvice"/>
xml 的springAOP配置
<!--SpringAOP的配置-->
<aop:config>
<!--配置切面 (切入点+通知)-->
<!-- ref:通知类 -->
<aop:aspect ref="advice">
<!-- id:切入点的唯一标识 expression:切入点表达式 -->
<aop:pointcut id="pc" expression="execution(* com.zdq.service.*.*.*(..))"/>
//配置切入点,范围就是expression
这个切入点表达式简写原理:service包下所有包.所有类.所有方法(..):两个点表示任意参数
public void com.zdq.service.impl.UserServiceImpl.addUser(User user); 简化1:void com.zdq.service.impl.UserServiceImpl.addUser(User user); 简化2:* com.zdq.service.impl.UserServiceImpl.addUser(User user); 简化3:* com.zdq.service.*.*.*.*(..);
注意:在切面里面配置切入点 和通知/增强
通知
method:增强方法 pointcut-ref:对应的切入点id
<aop:before method="before" pointcut-ref="pc"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="pc"/>
<aop:after-returning method="afterReturning" pointcut-ref="pc"/>
<aop:after method="after" pointcut-ref="pc"/>
环绕通知:可以替代以上四种通知
<aop:around method="around" pointcut-ref="pc"/>
注意:环绕通知必须加: 才能调用用户原有的方法
Object proceed = point.proceed()
解析:preceed就是调用原方法的返回值 还要return
return proceed;
基于注解去配置Aop
1:在通知类 加入注解
@Component //添加到ioc容器
@Aspect //切面声明
2:在通知方法上面 加入注解
@Before ("execution(* com.zdq.service.*.*(..)))
@After(..........)
@AfterReturing(...........)
@AfterThowing(.......)
Spring 声明式事务管理
导包:spring-tx aspectweaver
spring 通知类:TxAdvice
<tx:advice>
<tx:method name ="" isolation="" propagation="" read-only="" timeout=""/>
</tx:advice>
什么是事务传播行为?? 前两个是开发常用的
只有增删改 才会用到事务 REQUIRED : 改动(增删改) supports 查询
一般的通知配置
在通知类需要加入一下配置(transaction-manager是默认的可以不写)
使用事务管理器进行回滚
声明式 事务管理
配置事务过滤
<tx:method name="select*" isolation="DEFAULT" propagation="SUPPORTS" read-only="true" timeout="-1" /> <tx:method name="query*" isolation="DEFAULT" propagation="SUPPORTS" read-only="true" timeout="-1" /> <tx:method name="find*" isolation="DEFAULT" propagation="SUPPORTS" read-only="true" timeout="-1" /> <tx:method name="search*" isolation="DEFAULT" propagation="SUPPORTS" read-only="true" timeout="-1" /> <tx:method name="*" isolation="DEFAULT" propagation="REQUIRED" read-only="false" timeout="-1" /> </tx:attributes>
注解式事务管理配置文件
<?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:aop="http://www.springframework.org/schema/aop"
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/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--Spring声明式事务配置-->
<import resource="applicationContext-mybatis.xml"/>
<!--配置事务管理器(TxUtils)-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注意:保证Mybatis使用的数据源和事务管理器的数据源要一致-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启Spring事务的包扫描 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
在service方法上面加事务管理:
@Service @Transactional public class AccountServiceImpl implements AccountService {。。。}