AOP五种执行时机

Posted yimengxianzhi

tags:

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

动态代理四种增强方式

先创建一个service类

package com.zzj.calculatar.service;
import org.springframework.stereotype.Service;

@Service
public class CalculatorService implements ICalculatorService{

    @Override
    public int mul(int a, int b) {
        return a*b;
    }

    @Override
    public int div(int a, int b) {
        return a/b;
    }
    
}

XML文件

<context:component-scan base-package="com.zzj"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

四种增强:前置增强,后置增强,返回增强,异常增强

@Order(1)//切片执行顺序,默认为字典顺序
@Aspect
@Component
public class CalculatorAspect {

    @Pointcut("execution(public int com.zzj.calculatar.service.CalculatorService.*(..))")
    public void pointCut(){
        
    }
    
    //前置增强:目标方法执行之前先调用增强方法
    @Before("pointCut()")
    public void before(JoinPoint jp){
        //获取参数
        Object [] args = jp.getArgs();    
        //获取方法名
        Signature signature = jp.getSignature();
        String name = signature.getName();
        
        System.out.println("The "+ name +" method begins.");
        System.out.println("Parameters of the "+name+" method["+args[0]+","+args[1]+"]");
    }
    
    //后置增强:目标方法执行之后调用增强方法
    @After("pointCut()")
    public void after(JoinPoint jp){
        //获取方法名
        Signature signature = jp.getSignature();
        String name = signature.getName();
        System.out.println("The "+ name +" method ends.");
    }
    
    //返回增强:目标方法执行return之后返回结果之前调用增强方法,如果出异常则不执行
    @AfterReturning(value="pointCut()",returning = "result")
    public void afterReturning(JoinPoint jp,Object result){
        //获取方法名
        Signature signature = jp.getSignature();
        String name = signature.getName();
        System.out.println("The "+ name +" method results:"+result);
    }
    
    //异常增强:目标方法执行产生异常调用增强方法
    @AfterThrowing(value="pointCut()",throwing = "e")
    public void afterReturning(JoinPoint jp,Exception e){
        //获取方法名
        Signature signature = jp.getSignature();
        String name = signature.getName();
        System.out.println("The "+ name +" method exception:"+e);
    }
}

测试类:

public class Test {

    public static void main(String[] args){
        
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
        System.out.println(calculatorService.getClass());//当有代理类时,获取的代理对象
        System.out.println(calculatorService.div(1,1));
        applicationContext.close();
        
    }
    
}

测试结果:

技术图片

 

 当把除法的分母1改为0出现异常时,测试结果:

技术图片

 

 环绕增强,包含前面四种增强

@Order(1)//切片执行顺序,默认为字典顺序
@Aspect
@Component
public class CalculatorAspect {

    @Pointcut("execution(public int com.zzj.calculatar.service.CalculatorService.*(..))")
    public void pointCut(){
        
    }
    //环绕增强
    @Around(value="pointCut()")
    public Object around(ProceedingJoinPoint joinPoint){
        Object result = null;
        Object target = joinPoint.getTarget();//目标对象
        String methodName = joinPoint.getSignature().getName();
        Object[] params = joinPoint.getArgs();
        
        try{
            try{
                //前置增强
                System.out.println(target.getClass().getName()+": The "+methodName+" method begins.");
                System.out.println(target.getClass().getName()+": Parameters of the "+methodName+"method: ["+params[0]+","+params[1]+"]");
                //执行目标对象内的方法
                result = joinPoint.proceed();
            }finally{
                //后置增强
                System.out.println(target.getClass().getName()+":The "+methodName+" method ends.");
            }
            //返回增强
            System.out.println(target.getClass().getName()+":Result of the "+methodName+" method:"+result);
        }catch (Throwable e) {
            System.out.println(target.getClass().getName()+":Exception of the method "+methodName+": "+e);
        }
        return result;
    }
    
}

测试类:

public class Test {

    public static void main(String[] args){
        
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
        System.out.println(calculatorService.getClass());//当有代理类时,获取的代理对象
        System.out.println(calculatorService.div(1,1));
        applicationContext.close();
        
    }
    
}

测试结果:

技术图片

 

当把除法分母1改为0,报错时测试结果如下:

技术图片

 

以上是关于AOP五种执行时机的主要内容,如果未能解决你的问题,请参考以下文章

Spring-AOP的五种通知方式

AOP切入点表达式有哪五种通知类型

Spring AOP(转)

AOP:选择正确的时机进行编织

重温Spring之AOP

Spring实现AOP的4种方式