zoukankan      html  css  js  c++  java
  • 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参数在通知中与其他参数一起联用时,参数位置必须位于第一位.否则报错.

  • 相关阅读:
    attr系列
    面对对象中的反射
    Python中的内置函数(比较重要的)
    过滤莫文件夹下所有文件和子文件夹中的文件,并把路径打印出-----面对过程的编程
    python中字典的几个方法介绍
    python中字符串的几个方法介绍
    python中列表与元组
    win7上python2.7连接mysql数据库
    练习-三级菜单
    练习-模拟商城购物车
  • 原文地址:https://www.cnblogs.com/pxffly/p/7698825.html
Copyright © 2011-2022 走看看