From 1f140d5632e4e9e76ff32ab907b4cca9b35ecaca Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 9 Feb 2009 18:32:21 +0000 Subject: [PATCH] revised advice ordering (for async execution interceptor) git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@609 50f2f4bb-b051-0410-bef5-90022cba6387 --- .../annotation/AspectJProxyFactory.java | 23 ++++++------------ .../AbstractAdvisorAutoProxyCreator.java | 4 ++-- .../ExposeInvocationInterceptor.java | 24 ++++++++++--------- .../aop/support/AbstractPointcutAdvisor.java | 15 +++++++++--- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.java b/org.springframework.aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.java index 55f684956da..796270c58f5 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.aop.aspectj.annotation; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -27,6 +28,7 @@ import org.springframework.aop.aspectj.AspectJProxyUtils; import org.springframework.aop.framework.AopConfigException; import org.springframework.aop.framework.ProxyCreatorSupport; import org.springframework.aop.support.AopUtils; +import org.springframework.core.OrderComparator; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -116,10 +118,11 @@ public class AspectJProxyFactory extends ProxyCreatorSupport { * @see #makeAdvisorChainAspectJCapableIfNecessary() */ private void addAdvisorsFromAspectInstanceFactory(MetadataAwareAspectInstanceFactory instanceFactory) { - List advisors = this.aspectFactory.getAdvisors(instanceFactory); + List advisors = this.aspectFactory.getAdvisors(instanceFactory); advisors = AopUtils.findAdvisorsThatCanApply(advisors, getTargetClass()); - addAllAdvisors((Advisor[]) advisors.toArray(new Advisor[advisors.size()])); - makeAdvisorChainAspectJCapableIfNecessary(); + AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors); + Collections.sort(advisors, new OrderComparator()); + addAdvisors(advisors); } /** @@ -154,18 +157,6 @@ public class AspectJProxyFactory extends ProxyCreatorSupport { return instanceFactory; } - /** - * Add any special-purpose {@link Advisor Advisors} needed for AspectJ support - * to the chain. {@link #updateAdvisorArray() Updates} the {@link Advisor} array - * and fires {@link #adviceChanged events}. - */ - private void makeAdvisorChainAspectJCapableIfNecessary() { - if (AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(getAdvisorsInternal())) { - updateAdvisorArray(); - adviceChanged(); - } - } - /** * Get the singleton aspect instance for the supplied aspect type. An instance * is created if one cannot be found in the instance cache. diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java b/org.springframework.aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java index 56262b29889..3ce11a21afe 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,10 +86,10 @@ public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyC protected List findEligibleAdvisors(Class beanClass, String beanName) { List candidateAdvisors = findCandidateAdvisors(); List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); + extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } - extendAdvisors(eligibleAdvisors); return eligibleAdvisors; } diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/interceptor/ExposeInvocationInterceptor.java b/org.springframework.aop/src/main/java/org/springframework/aop/interceptor/ExposeInvocationInterceptor.java index 176f3174bbb..35970088048 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/interceptor/ExposeInvocationInterceptor.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/interceptor/ExposeInvocationInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.Advisor; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.core.NamedThreadLocal; +import org.springframework.core.Ordered; /** * Interceptor that exposes the current {@link org.aopalliance.intercept.MethodInvocation} @@ -39,7 +40,7 @@ import org.springframework.core.NamedThreadLocal; * @author Rod Johnson * @author Juergen Hoeller */ -public class ExposeInvocationInterceptor implements MethodInterceptor, Serializable { +public class ExposeInvocationInterceptor implements MethodInterceptor, Ordered, Serializable { /** Singleton instance of this class */ public static final ExposeInvocationInterceptor INSTANCE = new ExposeInvocationInterceptor(); @@ -49,17 +50,14 @@ public class ExposeInvocationInterceptor implements MethodInterceptor, Serializa * Spring AOP, as it prevents the need to create a new Advisor to wrap the instance. */ public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) { - @Override - public int getOrder() { - return Integer.MIN_VALUE; - } @Override public String toString() { return ExposeInvocationInterceptor.class.getName() +".ADVISOR"; } }; - private static final ThreadLocal invocation = new NamedThreadLocal("Current AOP method invocation"); + private static final ThreadLocal invocation = + new NamedThreadLocal("Current AOP method invocation"); /** @@ -69,7 +67,7 @@ public class ExposeInvocationInterceptor implements MethodInterceptor, Serializa * or if the ExposeInvocationInterceptor was not added to this interceptor chain */ public static MethodInvocation currentInvocation() throws IllegalStateException { - MethodInvocation mi = (MethodInvocation) invocation.get(); + MethodInvocation mi = invocation.get(); if (mi == null) throw new IllegalStateException( "No MethodInvocation found: Check that an AOP invocation is in progress, " + @@ -85,16 +83,20 @@ public class ExposeInvocationInterceptor implements MethodInterceptor, Serializa } public Object invoke(MethodInvocation mi) throws Throwable { - Object old = invocation.get(); + MethodInvocation oldInvocation = invocation.get(); invocation.set(mi); try { return mi.proceed(); } finally { - invocation.set(old); + invocation.set(oldInvocation); } } - + + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE + 1; + } + /** * Required to support serialization. Replaces with canonical instance * on deserialization, protecting Singleton pattern. diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java b/org.springframework.aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java index 182ad2d8030..a9031bcc3c0 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/support/AbstractPointcutAdvisor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ package org.springframework.aop.support; import java.io.Serializable; +import org.aopalliance.aop.Advice; + import org.springframework.aop.PointcutAdvisor; import org.springframework.core.Ordered; import org.springframework.util.ObjectUtils; @@ -34,7 +36,7 @@ import org.springframework.util.ObjectUtils; */ public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable { - private int order = Ordered.LOWEST_PRECEDENCE; + private Integer order; public void setOrder(int order) { @@ -42,7 +44,14 @@ public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordere } public int getOrder() { - return this.order; + if (this.order != null) { + return this.order; + } + Advice advice = getAdvice(); + if (advice instanceof Ordered) { + return ((Ordered) advice).getOrder(); + } + return Ordered.LOWEST_PRECEDENCE; } public boolean isPerInstance() {