spring 中的aop:advisor和aop:aspect的区别
在AOP中有几个概念:
— 方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现。
— 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
— 通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。
— 切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。
所以aop:aspect实际上是定义横切逻辑,就是在连接点上做什么,aop:advisor则定义了在哪些连接点上应用什么aop:aspect。Spring这样做的好处就是可以让多个横切逻辑 (即aop:aspect定义的)多次使用,提供可重用性。
总的来说:
1、Adivisor是一种特殊的Aspect,Advisor代表spring中的Aspect
2、advisor只持有一个Pointcut和一个advice,而aspect可以多个pointcut和多个advice
<!-- 准备工作: 导入aop名称空间 -->
<!-- 1. 配置目标对象-->
<bean name="userService" class="com.tz.service.UserServiceImpl"></bean>
<!-- 2. 配置通知对象-->
<bean name="myAdvice" class="com.tz.service.MyAdvice"></bean>
<aop:config>
<!-- 配置切入点
execution(* com.xyz.myapp.service.*.*(..))
public void com.tz.service.UserServiceImpl.savle()
* com.tz.service.UserServiceImpl.*() //public 可以省略
* com.tz.service.*ServiceImpl.*(..) //..表示可变参 //以ServiceImpl结尾的切入点
* com.tz.service..*ServiceImpl.*(..) //如果serive下面还有其它层,用..
-->
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* com.tz.service..*ServiceImpl.*(..))" id="pointcut"/>
<!-- 配置切面: 切入点+通知 -->
<aop:aspect ref="myAdvice">
<!-- 前置通知 -->
<aop:before method="before" pointcut-ref="pointcut"/>
<!-- 后置通知(如果出现异常不会调用) -->
<aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut"/>
<!-- 异常拦截通知 -->
<aop:after-throwing method="afterException" pointcut-ref="pointcut"/>
<!-- 后置通知(无论是否出现异常都会调用) -->
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
<!-- 配置事物通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 以方法为单位 ,指定方法应用那个事物属性
isolation:隔离级别 - 1 读未提交 2 读已提交 4可重复读 8 串行化
propagation:传播行为
read-only:是否只读
-->
<tx:method name="udpate*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<!--<tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
<tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
<tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/> -->
<tx:method name="tranAccount*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- 配置织入 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* com.tz.service..*ServiceImpl.*(..))" id="pointcut"/>
<!-- 配置切面: 切入点+通知
advice-ref:通知的名字 | pointcut-ref:切入点的名称 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>