@Around注解
上篇简述了AspectJ支持@Before、@After、@AfterReturning和@AfterThrowing及其执行过程,本模块来阐述其支持的另一种注解:@Around注解。
该注释修饰的方法可以灵活调整目标方法的执行时机;通过@Around注解还可以实现@Before,@After,@AfterReturning和@AfterThrowing增强效果。
下面将按照图中方式进行实现:
代码如下:
@Around("pointcut()")
public Object around(ProceedingJoinPoint jp){
try{
String name = jp.getSignature().getName();
Object result = null;
try {
Object [] args = jp.getArgs();
System.out.println("The "+name+" method begins");
System.out.println("The parameters of the "+name+" method are "+args[0]+","+args[1]);
result = jp.proceed();
}finally {
System.out.println("The "+name+" method ends");
}
System.out.println("The "+name+" method result:"+result);
return result;
}catch (Throwable e){
System.out.println("#############"+e.getMessage());
}
return -1;
}
代码修改后,Test运行结果如下:
由图可以看出,通过@Around注解可以完全实现@Before,@After,@AfterReturning和@AfterThrowing增强效果。
@Pointcut注解:
通过观察CalculatorAspect类中前面的代码可以发现,在@Before,@After,@AfterReturning、@AfterThrowing和@Around注解中切入点表达式均由pointcut()替代。
是因为@Before,@After,@AfterReturning、@AfterThrowing和@Around注解中切入点表达式相同,为了简化代码,我们选择通过单独自定义一个@Pointcut注解修饰的空方法的方式,对@Before,@After,@AfterReturning、@AfterThrowing和@Around注解中的切入点表达式进行简化,具体代码如下:
@Pointcut("execution(public int com.jd.calculator.service.CalculatorService.*(..))")
public void pointcut(){
}
XML配置AOP
通过XML配置AOP是Spring框架专有的,但由于AspectJ得到越来越多的AOP框架支持,所以通过注解实现AOP将会有更多重用的机会。通过XML配置实现AOP。
CalculatorAspect类中代码展示:
package com.jd.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
public class CalculatorAspect {
@Pointcut("execution(public int com.jd.calculator.service.CalculatorService.*(..))")
public void pointcut(){
}
public void before(JoinPoint jp){
Object [] args = jp.getArgs();
String name = jp.getSignature().getName();
System.out.println("The "+name+" method begins");
System.out.println("The parameters of the "+name+" method are "+args[0]+","+args[1]);
}
public void after(JoinPoint jp){
String name = jp.getSignature().getName();
System.out.println("The "+name+" method ends");
}
public void afterReturning(JoinPoint jp,Object obj){
String name = jp.getSignature().getName();
System.out.println("The "+name+" method result:"+obj);
}
public void afterThrowing(JoinPoint jp,Throwable e){
System.out.println("#############"+e.getMessage());
e.printStackTrace();
}
}
application.xml文件代码展示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="calculatorAspect" class="com.jd.aspect.CalculatorAspect"></bean>
<aop:config>
<aop:pointcut id="p" expression="execution(public int com.jd.calculator.service.CalculatorService.*(..))"/>
<aop:aspect ref="calculatorAspect">
<aop:before pointcut-ref="p" method="before"></aop:before>
<aop:after pointcut-ref="p" method="after"></aop:after>
<aop:after-returning pointcut-ref="p" method="afterReturning" returning="obj"></aop:after-returning>
<aop:after-throwing pointcut-ref="p" method="afterThrowing" throwing="e"></aop:after-throwing>
</aop:aspect>
</aop:config>
以此种方法实现在XML文件中实现AOP。