AOP面向切面编程

Posted 狂妄的老头

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AOP面向切面编程相关的知识,希望对你有一定的参考价值。

先写一段正确的执行程序的代码,然后对其进行面向切面编程(AOP)

1,准备切面(就是下面的这个TxAspect)

2,准备连接点(就是测试类中的目标方法)

3.编写通知(就是TxAspect中的前置、后置、异常、最终、环绕通知)

另:

前置、后置、异常、最终通知都不能影响目标方法执行,而环绕通知能控制目标方法执行。

另:

Proceedingjoinpoint 继承了 JoinPoint 。是在JoinPoint的基础上暴露出 proceed 这个方法。proceed很重要,这个是aop代理链执行的方法。暴露出这个方法,就能支持 aop:around 这种切面(而其他的几种切面只需要用到JoinPoint,这跟切面类型有关), 能决定是否走代理链还是走自己拦截的其他逻辑。

在ProceedingJoinPoint中只有proceed()方法,用来控制目标方法执行.那么该参数只能用到 环绕通知中。

 

4.编写切面配置(就是最后面的配置信息 expression() 是细粒度的 匹配规则,粗粒度的使用within() 根据类进行匹配)

 

 

 1 package aspect;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 import org.springframework.stereotype.Component;
 6 
 7 //切面
 8 @Component
 9 public class TxAspect {
10     //通知
11     public void before(JoinPoint joinPoint){
12         System.out.println("我是一个前置通知方法");
13         //获取目标对象的类型
14         Class targetClass = joinPoint.getTarget().getClass();
15         //获取目标方法的名称
16         String methodName = joinPoint.getSignature().getName();
17         System.out.println("目标对象:"+targetClass);
18         System.out.println("目标方法:"+methodName);
19     }
20     
21     
22     public void after(JoinPoint joinpoint){
23         System.out.println("我是一个后置通知方法");
24         Class targetClass = joinpoint.getTarget().getClass();
25         String methodName = joinpoint.getSignature().getName();
26         System.out.println("目标对象:"+targetClass);
27         System.out.println("目标方法:"+methodName);
28     }
29     public void afterThrow(JoinPoint joinPoint,Throwable throwable){
30         System.out.println("我是一个异常通知");
31         Class throwClass = throwable.getClass();
32         String msg = throwable.getMessage();
33         System.out.println("异常的类型为:"+throwClass);
34         System.out.println("异常的信息为:"+msg);
35     }
36     public void afterAdvice(){
37         System.out.println("我是一个最终通知");
38     }
39     
40     public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
41         System.out.println("环绕通知开始");
42         Object result = joinPoint.proceed();
43         System.out.println("环绕通知结束");
44         return null;
45                 
46     }
47     
48     
49 }

 

 1    <context:component-scan base-package="service,aspect"/>
 2    
 3    <aop:config>
 4            <aop:pointcut expression="execution(* service..*.*(..))" id="pc"/>
 5            <aop:aspect ref="txAspect">
 6                <aop:before method="before" pointcut-ref="pc"/>
 7                <aop:after method="after" pointcut-ref="pc"/>
 8                <aop:after-throwing method="afterThrow" pointcut-ref="pc" throwing="throwable"/>
 9                <aop:after-returning method="afterAdvice" pointcut-ref="pc"/>
10                <aop:around method="around" pointcut-ref="pc" />
11            </aop:aspect>
12    </aop:config>

 

不出错的话结果是这样:

我是一个前置通知方法
目标对象:class service.UserServiceImpl
目标方法:updateUser
环绕通知开始
更新用户信息
环绕通知结束
我是一个最终通知
我是一个后置通知方法
目标对象:class service.UserServiceImpl
目标方法:updateUser

出错的话,最终通知不会执行,环绕通知不会正确结束

我是一个前置通知方法
目标对象:class service.UserServiceImpl
目标方法:addUser
环绕通知开始
添加一个用户
我是一个异常通知
异常的类型为:class java.lang.ArithmeticException
异常的信息为:/ by zero
我是一个后置通知方法
目标对象:class service.UserServiceImpl
目标方法:addUser

 最后:

如果JoinPoint joinPoint参数在通知中与其他参数一起联用时,参数位置必须位于第一位.否则报错.

以上是关于AOP面向切面编程的主要内容,如果未能解决你的问题,请参考以下文章

Spring的AOP面向切面编程

面向切面编程

Spring的AOP面向切面编程

三面向切面编程

面向切面编程AOP是面向对象编程OOP的补充

Spring的AOP面向切面编程