切面中不同注解的切入点的执行顺序为:前置处理、后置处理、返回处理/异常处理,这个顺序是很好理解的。但是如果定义了多个切面类,并且里面有相同的处理环节时,如果不手动指定处理顺序,那么他们将按照字母顺序执行,如果指定了执行顺序,那么将按照指定的顺序执行。下面就来说明一下使用AOP的两种方式中是如何指定相同处理环节的执行顺序的。还是以处理下面的service层代码为例:
package cn.jingpengchong.calculator.service;
import org.springframework.stereotype.Service;
@Service
public class CalculatorService implements ICalculatorService {
public int div(int a, int b) {
return a/b;
}
}
注解方式指定执行顺序
这种方式需要在切面类前面加上@Order()注解,括号里面的参数值越小,越先执行。
1、新建模块“cn.jingpengchong.aspect”,然后新建“ArgsAspect.java”和“MethodAspect.java”文件:
package cn.jingpengchong.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
//指定第二个执行
@Order(2)
@Aspect
@Component
public class ArgsAspect {
@Before("execution(public int cn.jingpengchong.calculator.service.CalculatorService.*(..))")
public void before(JoinPoint jp) {
Object[] args = jp.getArgs();
Signature signature = jp.getSignature();
String name = signature.getName();
System.out.println("日志:The " + name + " method args:[" + args[0] + "," + args[1] + "]");
}
}
package cn.jingpengchong.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
//指定第一个执行
@Order(1)
@Aspect
@Component
public class MethodAspect {
@Before("execution(public int cn.jingpengchong.calculator.service.CalculatorService.*(..))")
public void before(JoinPoint jp) {
Signature signature = jp.getSignature();
String name = signature.getName();
System.out.println("日志:The " + name + " method begins");
}
}
2、spring的xml配置文件中指定自动代理:
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
3、编写测试类:
package cn.jingpengchong.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.jingpengchong.calculator.service.ICalculatorService;
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.div(6, 2));
applicationContext.close();
}
}
运行结果如下:
xml配置方式指定执行顺序
这种方式需要在<aop:aspect>标签加上order属性,order属性的属性值越小,越先执行。
1、新建模块“cn.jingpengchong.aspect”,然后新建“ArgsAspect.java”和“MethodAspect.java”文件:
package cn.jingpengchong.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
public class ArgsAspect {
public void before(JoinPoint jp) {
Object[] args = jp.getArgs();
Signature signature = jp.getSignature();
String name = signature.getName();
System.out.println("日志:The " + name + " method args:[" + args[0] + "," + args[1] + "]");
}
}
package cn.jingpengchong.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
public class MethodAspect {
public void before(JoinPoint jp) {
Signature signature = jp.getSignature();
String name = signature.getName();
System.out.println("日志:The " + name + " method begins");
}
}
2、spring的xml配置文件中配置切面:
<bean id = "argsAspect" class = "cn.jingpengchong.aspect.ArgsAspect"/>
<bean id = "methodAspect" class = "cn.jingpengchong.aspect.MethodAspect"/>
<aop:config>
<aop:pointcut expression="execution(public int cn.jingpengchong.calculator.service.CalculatorService.*(..))" id="pointCut"/>
<aop:aspect ref="argsAspect" order="2">
<aop:before method="before" pointcut-ref="pointCut"/>
</aop:aspect>
<aop:aspect ref="methodAspect" order="1">
<aop:before method="before" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>
3、编写测试类:
package cn.jingpengchong.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.jingpengchong.calculator.service.ICalculatorService;
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.div(6, 2));
applicationContext.close();
}
}
运行结果如下: