zoukankan      html  css  js  c++  java
  • Spring4.0学习笔记(11) —— Spring AspectJ 的五种通知

    Spring AspectJ

    一、基于注解的方式配置通知

    1、额外引入的jar包:

      a) com.springsource.org.aopalliance-1.0.0.jar

      b) com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

      c) spring-aop-4.0.0.RELEASE.jar

      d) spring-aspects-4.0.0.RELEASE.jar

    2、在xml中加入aop 的命名空间

      xmlns:aop="http://www.springframework.org/schema/aop"

      //自动为匹配的类生成代理对象

      <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    3、把横切关注点的代码抽象到切面的类中

      a) 切面首先是一个 IOC 的bean,即加入@Component 注解

      b) 切面还需要加入@Aspect

    4、在类中声明各种通知

      a) @before 前置通知 在方法执行之前执行

        a.i) AspectJ 表达式 : @Before("execution(*1 com.spring.springaop.*2.*3(...))") //*1 代表 所有类型的返回值;*2 代表 所有的类;*3 代表所有方法   

        public class LoggingAspect{
            public void beforeMethod(JointPoint joinPoint){
                String methodName = joinPoint.getSignature().getName();
                List<Object> args = Arrays.asList(joinPoint.getArgs());
            }
        }

      b) @After 后置通知 在方法执行之后执行,无论是否发生异常

      c) @AfterReturning 返回通知 在方法返回结果之后执行 [在方法正常结束后返回的通知]

        c.i) 返回通知是可以访问到方法的返回值的

        c.ii) @AfterReturning(value="execution(public int com.spring.springaop.*.*(..))",returning="result")

        c.iii) public void afterReturning(JointPoint jointPoint,Object result) {}

      d) @AfterThrowing 异常通知 在方法抛出异常之后执行

        d.i) @AfterThrowing(value="execution(public int com.spring.springaop.*.*(..))",throwing="ex")

        d.ii) public void afterThrowing(JointPoint jointPoint,Exception ex【NullPointerException ex】) {} 

        d.iii) 可以访问到异常对象,且可以指定在出现特定异常时再执行通知代码【如果是NullPointerException ,则不会在数学计算出现错误时执行,而仅仅会在空指针时才会报异常】

      e) @Around 环绕通知 围绕着方法执行

        e.i) 环绕通知需要携带ProceedingJointPoint类型的参数

         e.ii) 环绕通知类似于动态代理的全过程、 ProceedingJointPoint 类型的参数可以决定是否执行目标方法、且环绕通知必须有返回值,返回值即为

    目标方法的返回值

        public Object aroundMethod(ProcessdingJoinPoint pjd)
        {
            Object object = null;
            String method = pjd.getSignature().getName();
            
            try {
                //前置通知
                System.out.println(Arrays.asList(pjd.getArgs()));
                //执行目标方法
                object = pjd.proceed();
                //返回通知
                System.out.println(object);
            } catch (Exception e) {
                //异常通知
                System.out.println(e);
            }
            //后置通知
            System.out.println("ends");
            return object;
        }

    5、可以在通知方法中声明一个类型为JointPoint 的参数,就能访问链接细节,如方法名称和参数值 

    6、优先级 @Order(0) 值越小,越优先

    7、重用切点表达式

      7.i) 一般情况下不需要插入其他代码,@PointCut 来声明切入点表达式,后面的advisor 直接使用方法来引入当前的切入点表达式

      @PointCut("execution(public int com.spring.springaop.*.*(..))")

      public void declareJointPointExpression() {}

      @Before("declareJointPointExpression()")

      public void beforeMethod(){.../}

    二、基于xml方式

      //配置bean

      //配置切面的bean

      //配置aop

      <aop:config>

        //配置切点表达式

        <aop:pointcut expression="execution(public int com.spring.springaop.*.*(..)))" id="pointcut"/> 

        //配置切面及通知

        <aop:aspect ref="切面bean的id" order ="2">

          <aop:before method="beforeMethod" pointcut-ref="pointcut"></aop:before>

          <aop:after method="afterMethod" pointcut-ref="pointcut"></aop:after>

          <aop:throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"></aop:throwing>

          <aop:returning method="afterReturning" pointcut-ref="pointcut" returning="result"></aop:returning>

        </aop:aspect>

      </aop:config>

  • 相关阅读:
    C字符串和C++字符串
    Linux的用户态和内核态
    知乎问答:如何理解“In UNIX, everything is a file”?
    科普:并行计算、分布式计算、集群计算和云计算
    个人使用VIM的一些总结
    C语言回调函数学习
    Python的函数参数传递:传值?引用?
    ECMAScript 函数函数概述
    ECMAScript 函数arguments 对象
    ECMAScript 语句with 语句
  • 原文地址:https://www.cnblogs.com/cklovefan/p/5325470.html
Copyright © 2011-2022 走看看