11. Spring之AOP细节

Spring之AOP细节

1. 细节一

通知方法的执行顺序:

  1. 正常执行:@Before前置通知 -- @After后置通知 -- @AfterReturning正常返回
  2. 异常执行:@Before前置通知 -- @After后置通知 -- @AfterThrowing方法异常
2. 细节二

切入点表达式通常都会是从宏观上定位一组方法,和具体某个通知的注解结合起来就能够确定对应的连接点。那么就一个具体的连接点而言,我们可能会关心这个连接点的一些具体信息,例如:当前连接点所在方法的方法名、当前传入的参数值等等。这些信息都封装在JoinPoint接口的实例对象中。

  1. 只需要为通知方法的参数列表上写一个参数,JoinPoint joinPoint:封装了当前目标方法的详细信息。
  2. jointPoint.getArgs() 获取目标方法运行时使用的参数
  3. joinPoint.getSignature() 获取到方法签名
  4. signature.getName() 获得方法名
  5. public static void logStart(JoinPoint joinPoint);
3. 细节三
  1. @AfterThrowing(value = "execution(省略...)",throwing = "e")
    1. public static void logError(JoinPoint joinPoint,Exception e)
  2. @AfterReturning(value = "execution(省略...)",returning = "result")
  3. public static void logFinally(JoinPoint joinPoint,Object result)
  4. 注意returning 和throwing是在上面@AfterReturning和@AfterThrowing两个注解中使用的。
  5. Spring对通知方法要求不严格,唯一要求的是:方法的参数列表一定不能乱写。
    // 想在执行目标方法之前运行,写切入点表达式
    // execution(访问权限符 返回值类型 方法签名)
    @Before(value = "execution(public int cn.justweb.calculator.impl.CalculatorImpl.*(int,int))")
    public static void logStart(JoinPoint joinPoint){
        System.out.println("["+joinPoint.getSignature().getName()+"]:方法执行了,其参数列表为"+Arrays.asList(joinPoint.getArgs()));
    }

    @After(value = "execution(public int cn.justweb.calculator.impl.CalculatorImpl.*(int,int))")
    public static void logEnd(JoinPoint joinPoint){
        System.out.println("["+joinPoint.getSignature().getName()+"]:方法正常执行完成了");
    }
    @AfterThrowing(value = "execution(public int cn.justweb.calculator.impl.CalculatorImpl.*(int,int))",throwing = "e")
    public static void logError(JoinPoint joinPoint,Exception e){
        System.out.println("["+joinPoint.getSignature().getName()+"]:方法执行出现了异常,原因为:"+e.getCause());
    }

    @AfterReturning(value = "execution(public int cn.justweb.calculator.impl.CalculatorImpl.*(int,int))",returning = "result")
    public static void logFinally(JoinPoint joinPoint,Object result){
        System.out.println("["+joinPoint.getSignature().getName()+"]:方法最终执行完成了,其结果为"+result);
    }
4. 细节四

可重用的切入点表达式,具体见代码

  1. 在编写AspectJ切面时,可以直接在通知注解中书写切入点表达式。但同一个切点表达式可能会在多个通知中重复出现。
  2. 在AspectJ切面中,可以通过@Pointcut注解将一个切入点声明成简单的方法。
  3. 切入点的方法体通常是空的,因为将切入点定义与应用程序逻辑混在一起是不合理的。
  4. 切入点方法的访问控制符同时也控制着这个切入点的可见性。如果切入点要在多个切面中共用,最好将它们集中在一个公共的类中。在这种情况下,它们必须被声明为public。在引入这个切入点时,必须将类名也包括在内。如果类没有与这个切面放在同一个包中,还必须包含包名。

之前的切面类写法如上,通过可重用切入点表达式后的写法为:

    /**
     *抽取可重入的切入点表达式:
     * 1. 随便声明一个没有返回值的空方法
     */
    @Pointcut("execution(public int cn.justweb.calculator.impl.CalculatorImpl.*(int,int))")
    public void myPoint(){
     }

    @Before(value = "myPoint()")
    public static void logStart(JoinPoint joinPoint){
        System.out.println("["+joinPoint.getSignature().getName()+"]:方法执行了,其参数列表为"+Arrays.asList(joinPoint.getArgs()));
    }

    @After(value = "myPoint()")
    public static void logEnd(JoinPoint joinPoint){
        System.out.println("["+joinPoint.getSignature().getName()+"]:方法正常执行完成了");
    }
	
		//....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值