revised advice ordering (for async execution interceptor)

This commit is contained in:
Juergen Hoeller 2009-02-09 18:32:21 +00:00
parent fc6d7358ef
commit 0794756fba
4 changed files with 34 additions and 32 deletions

View File

@ -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<Advisor> 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.

View File

@ -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<Advisor> findEligibleAdvisors(Class beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
extendAdvisors(eligibleAdvisors);
return eligibleAdvisors;
}

View File

@ -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<MethodInvocation> invocation =
new NamedThreadLocal<MethodInvocation>("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.

View File

@ -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() {