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面向切面编程的主要内容,如果未能解决你的问题,请参考以下文章