spring aop的order执行顺序的奇怪现象
以我所知:用注解order可以用来控制aop的执行顺序。则是按照1>2>3这个顺序执行。
但是我这个例子却很奇怪,并不是按照这个顺序执行。
order1这个类,有2个around方式的拦截,一个是拦截注解
,一个是拦截方法
order2这个类,和order1中的拦截方法
,是同一个拦截方式
我理想中的执行顺序,应该是:order1拦截注解
> order1拦截方法
> order2拦截方法
但是实际的执行顺序,却是:order1拦截注解
> order2拦截方法
> order1拦截方法
于是我发现,无论如何设置order,必然都一定是拦截注解
会先执行。
所以这个现象究竟应该如何解释?难道是那个什么先执行的后返回?但是我这里没用到before和after啊
回答:
Spring的AOP执行顺序的参考文档如下:
http://docs.spring.io/spring/...
简单的说,@Aspect注解的Order是起效的,但同一个Aspect中的Advice是没有明确的执行顺序的,例如你Order(1)中的两个Advice.我们看以参考ReflectiveAspectJAdvisorFactory类的源码如下:
private static final Comparator<Method> METHOD_COMPARATOR; static {
CompoundComparator<Method> comparator = new CompoundComparator<Method>();
comparator.addComparator(new ConvertingComparator<Method, Annotation>(
new InstanceComparator<Annotation>(
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
new Converter<Method, Annotation>() {
@Override
public Annotation convert(Method method) {
AspectJAnnotation<?> annotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (annotation != null ? annotation.getAnnotation() : null);
}
}));
comparator.addComparator(new ConvertingComparator<Method, String>(
new Converter<Method, String>() {
@Override
public String convert(Method method) {
return method.getName();
}
}));
METHOD_COMPARATOR = comparator;
}
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new LinkedList<Advisor>();
for (Method method : getAdvisorMethods(aspectClass)) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
我们可以看到,其实Spring也就是按照方法名的对同级别Advice进行排序的.所以,如果想让同级别advice顺序执行,最好的办法就是,方法名按英文字母排列.我的测试代码如下:
@Around(value = "execution(* org.sagesource..*.*(..))") public Object aheckAuthPackage(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("----Order1:checkAuthPackage:Execution----");
Object[] args = joinPoint.getArgs();
return joinPoint.proceed(args);
}
@Around(value = "@annotation(org.sagesource.training.spring.aop.order.annotation.AuthAnnotation)")
public Object checkAuth(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("----Order1:checkAuth:Annotation----");
Object[] args = joinPoint.getArgs();
return joinPoint.proceed(args);
}
执行结果:
----Order1:checkAuthPackage:Execution----
----Order1:checkAuth:Annotation----
但是楼主说的实际执行顺序应该还是不对的,肯定是Order(1)的先执行.
回答:
不能使用CGlib 去生成动态代理,使用JDK去生成代理,spring xml配置如下:
<aop:aspectj-autoproxy />
之前配置如下Order 不起作用。换成上面的配置就好了.原因还不是很清楚,JDK生成的代理Debug 可以看到advisorArray,这个数组是排序后的advisor
<aop:aspectj-autoproxy proxy-target-class="true"/>
以上是 spring aop的order执行顺序的奇怪现象 的全部内容, 来源链接: utcz.com/p/175460.html