Bootstrap

AspectJ的五种增强注解

目录

前置增强

后置增强

返回增强

异常增强

前四种增强的执行过程及顺序

环绕增强


AspectJ一共支持5种类型的增强注解,@Before前置增强、@After后置增强、@AfterReturning返回增强、@AfterThrowing异常增强和@Around环绕增强

前置增强

@Before:前置增强,在目标方法执行之前执行

@Before(value="execution(int mul(int ,int ))")
public void before(JoinPoint jp) {
	Object obj=jp.getTarget();
	Object [] args=jp.getArgs();
	String name=jp.getSignature().getName();
	System.out.println(obj.getClass().getName()+":The "+name+" method begins.");
	System.out.println(obj.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
}
  • Object obj=jp.getTarget():获取目标对象
  • Object [] args=jp.getArgs():获取匹配方法的参数
  • String name=jp.getSignature().getName():获取匹配方法的方法名

后置增强

@After:后置增强,在目标方法执行后执行,无论目标方法运行期间是否出现异常,该增强注释的方法均会执行。注意:后置增强无法获取目标方法执行结果,可以在返回增强中获取

@After("value="execution(int mul(..))"")
public void after(JoinPoint jp) {
	Object obj=jp.getTarget();
	String name=jp.getSignature().getName();
	System.out.println(obj.getClass().getName()+":The "+name+" method ends.");
}

返回增强

@AfterReturning:返回增强,在目标方法正常结束后执行,可以获取目标方法的执行结果,如果目标方法运行异常则不执行

@AfterReturning(value="execution(int mul(..))",returning="a")
public void afterReturning(JoinPoint jp,Object a) {
	Object obj=jp.getTarget();
	String name=jp.getSignature().getName();
	System.out.println(obj.getClass().getName()+":Result of the "+name+" method:"+a);
}

注意:returning=“a”表示目标方法的返回值返回到a中,注意afterReturning方法中的Object类参数名要与returning值一致

异常增强

@AfterThrowing:异常增强,在目标方法运行期间出现异常时执行,否则不执行

@AfterThrowing(value="execution(int mul(..))",throwing="e")
public void afterThrowing(JoinPoint jp,RuntimeException e) {//此时的异常类必需为抛出异常的父类或相同异常,即此处的异常>=抛出的异常
	Object obj=jp.getTarget();
	String name=jp.getSignature().getName();
	System.out.println(obj.getClass().getName()+":The "+name+" method has a exception:"+e.getMessage());
}

注意:throwing=“e”用于接受目标方法抛出的异常,注意afterThrowing方法中的第二个参数名要与throwing的值一致,且第二个参数的异常类型要是目标方法抛出异常的父类或同类,否则出错

前四种增强的执行过程及顺序

try {
	try {
		//@Before注解所修饰的方法
		//执行目标对象内的方法
	}finally {
		//@After注解所修饰的方法
	}
	//@AfterReturning注解所修饰的方法
} catch (Throwable e) {
	//@AfterThrowing注解所修饰的方法
}

执行结果: 

//正常
com.jd.calculator.CalculatorService:The mul method begins.
com.jd.calculator.CalculatorService:Parameters of the mul method: [1,1]
com.jd.calculator.CalculatorService:The mul method ends.
com.jd.calculator.CalculatorService:Result of the mul method:1
-->1
//异常
com.jd.calculator.CalculatorService:The mul method begins.
com.jd.calculator.CalculatorService:Parameters of the mul method: [0,1]
com.jd.calculator.CalculatorService:The mul method ends.
com.jd.calculator.CalculatorService:The mul method has a exception:结果不能为0

执行顺序分析如下:

①前置增强--->目标方法--->目标方法出现异常--->finally中的后置增强--->catch中的异常增强

②前置增强--->目标方法--->目标方法不出现异常--->finally中的后置增强--->返回增强

环绕增强

@Around:环绕增强,在@Around修饰的方法中可以实现@Before,@After,@AfterReturning和@AfterThrowing的增强效果,可以实现动态代理的全过程,代码如下:

@Around(value="execution(int *(..))")
public Object around(ProceedingJoinPoint jp) {
	Object result=null;
	Object obj=jp.getTarget();
	Object [] args=jp.getArgs();
	String name=jp.getSignature().getName();
	try {
		try {
			//前置增强	
			System.out.println(obj.getClass().getName()+":The "+name+" method begins.");
			System.out.println(obj.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
			//目标方法	
			result=jp.proceed();
		} finally {
            //后置增强
			System.out.println(obj.getClass().getName()+":The "+name+" method ends.");
		}
        //返回增强
		System.out.println(obj.getClass().getName()+":Result of the "+name+" method:"+result);
	} catch (Throwable e) {
        //异常增强
		System.out.println(obj.getClass().getName()+":The "+name+" method has a exception:"+e.getMessage());
	}
	return result;
}

和如下代码等效:

//前置增强
@Before(value="execution(int mul(..))")
public void before(JoinPoint jp) {
	Object obj=jp.getTarget();
	Object [] args=jp.getArgs();
	String name=jp.getSignature().getName();
	System.out.println(obj.getClass().getName()+":The "+name+" method begins.");
	System.out.println(obj.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
}
//返回增强
@AfterReturning(value="execution(int mul(..))",returning="a")
public void afterReturning(JoinPoint jp,Object a) {
	Object obj=jp.getTarget();
	String name=jp.getSignature().getName();
	System.out.println(obj.getClass().getName()+":Result of the "+name+" method:"+a);
}
//后置增强
@After(value="execution(int mul(..))")
public void after(JoinPoint jp) {
	Object obj=jp.getTarget();
	String name=jp.getSignature().getName();
	System.out.println(obj.getClass().getName()+":The "+name+" method ends.");
}
//异常增强
@AfterThrowing(value="execution(int mul(..))",throwing="e")
public void afterThrowing(JoinPoint jp,RuntimeException e) {//此时的异常类必需为抛出异常的父类或相同异常,即此处的异常>=抛出的异常
    Object obj=jp.getTarget();
	String name=jp.getSignature().getName();
	System.out.println(obj.getClass().getName()+":The "+name+" method has a exception:"+e.getMessage());
}

运行结果:

com.jd.calculator.CalculatorService:The mul method begins.
com.jd.calculator.CalculatorService:Parameters of the mul method: [1,1]
com.jd.calculator.CalculatorService:The mul method ends.
com.jd.calculator.CalculatorService:Result of the mul method:1
-->1

注意:1、前四种增强修饰的方法可以通过声明JoinPoint 类型参数变量获取目标方法的信息(方法名、参数列表等信息);@Around修饰的方法必须声明ProceedingJoinPoint类型的参数,该变量可以决定是否执行目标方法,jp.proceed()表示执行目标方法

2、前四种增强修饰的方法没有返回值(即为void);而@Around修饰的方法必须有返回值,返回值为目标方法的返回值;

 

;