revised advice ordering (for async execution interceptor)
This commit is contained in:
parent
fc6d7358ef
commit
0794756fba
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.aop.aspectj.annotation;
|
package org.springframework.aop.aspectj.annotation;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.AopConfigException;
|
||||||
import org.springframework.aop.framework.ProxyCreatorSupport;
|
import org.springframework.aop.framework.ProxyCreatorSupport;
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
import org.springframework.core.OrderComparator;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
|
@ -116,10 +118,11 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||||
* @see #makeAdvisorChainAspectJCapableIfNecessary()
|
* @see #makeAdvisorChainAspectJCapableIfNecessary()
|
||||||
*/
|
*/
|
||||||
private void addAdvisorsFromAspectInstanceFactory(MetadataAwareAspectInstanceFactory instanceFactory) {
|
private void addAdvisorsFromAspectInstanceFactory(MetadataAwareAspectInstanceFactory instanceFactory) {
|
||||||
List advisors = this.aspectFactory.getAdvisors(instanceFactory);
|
List<Advisor> advisors = this.aspectFactory.getAdvisors(instanceFactory);
|
||||||
advisors = AopUtils.findAdvisorsThatCanApply(advisors, getTargetClass());
|
advisors = AopUtils.findAdvisorsThatCanApply(advisors, getTargetClass());
|
||||||
addAllAdvisors((Advisor[]) advisors.toArray(new Advisor[advisors.size()]));
|
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors);
|
||||||
makeAdvisorChainAspectJCapableIfNecessary();
|
Collections.sort(advisors, new OrderComparator());
|
||||||
|
addAdvisors(advisors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,18 +157,6 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
|
||||||
return instanceFactory;
|
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
|
* Get the singleton aspect instance for the supplied aspect type. An instance
|
||||||
* is created if one cannot be found in the instance cache.
|
* is created if one cannot be found in the instance cache.
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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) {
|
protected List<Advisor> findEligibleAdvisors(Class beanClass, String beanName) {
|
||||||
List<Advisor> candidateAdvisors = findCandidateAdvisors();
|
List<Advisor> candidateAdvisors = findCandidateAdvisors();
|
||||||
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
|
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
|
||||||
|
extendAdvisors(eligibleAdvisors);
|
||||||
if (!eligibleAdvisors.isEmpty()) {
|
if (!eligibleAdvisors.isEmpty()) {
|
||||||
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
|
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
|
||||||
}
|
}
|
||||||
extendAdvisors(eligibleAdvisors);
|
|
||||||
return eligibleAdvisors;
|
return eligibleAdvisors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.Advisor;
|
||||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||||
import org.springframework.core.NamedThreadLocal;
|
import org.springframework.core.NamedThreadLocal;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interceptor that exposes the current {@link org.aopalliance.intercept.MethodInvocation}
|
* Interceptor that exposes the current {@link org.aopalliance.intercept.MethodInvocation}
|
||||||
|
@ -39,7 +40,7 @@ import org.springframework.core.NamedThreadLocal;
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
*/
|
*/
|
||||||
public class ExposeInvocationInterceptor implements MethodInterceptor, Serializable {
|
public class ExposeInvocationInterceptor implements MethodInterceptor, Ordered, Serializable {
|
||||||
|
|
||||||
/** Singleton instance of this class */
|
/** Singleton instance of this class */
|
||||||
public static final ExposeInvocationInterceptor INSTANCE = new ExposeInvocationInterceptor();
|
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.
|
* Spring AOP, as it prevents the need to create a new Advisor to wrap the instance.
|
||||||
*/
|
*/
|
||||||
public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {
|
public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {
|
||||||
@Override
|
|
||||||
public int getOrder() {
|
|
||||||
return Integer.MIN_VALUE;
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return ExposeInvocationInterceptor.class.getName() +".ADVISOR";
|
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
|
* or if the ExposeInvocationInterceptor was not added to this interceptor chain
|
||||||
*/
|
*/
|
||||||
public static MethodInvocation currentInvocation() throws IllegalStateException {
|
public static MethodInvocation currentInvocation() throws IllegalStateException {
|
||||||
MethodInvocation mi = (MethodInvocation) invocation.get();
|
MethodInvocation mi = invocation.get();
|
||||||
if (mi == null)
|
if (mi == null)
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"No MethodInvocation found: Check that an AOP invocation is in progress, " +
|
"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 {
|
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||||
Object old = invocation.get();
|
MethodInvocation oldInvocation = invocation.get();
|
||||||
invocation.set(mi);
|
invocation.set(mi);
|
||||||
try {
|
try {
|
||||||
return mi.proceed();
|
return mi.proceed();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
invocation.set(old);
|
invocation.set(oldInvocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getOrder() {
|
||||||
|
return Ordered.HIGHEST_PRECEDENCE + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required to support serialization. Replaces with canonical instance
|
* Required to support serialization. Replaces with canonical instance
|
||||||
* on deserialization, protecting Singleton pattern.
|
* on deserialization, protecting Singleton pattern.
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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 java.io.Serializable;
|
||||||
|
|
||||||
|
import org.aopalliance.aop.Advice;
|
||||||
|
|
||||||
import org.springframework.aop.PointcutAdvisor;
|
import org.springframework.aop.PointcutAdvisor;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
@ -34,7 +36,7 @@ import org.springframework.util.ObjectUtils;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable {
|
public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable {
|
||||||
|
|
||||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
private Integer order;
|
||||||
|
|
||||||
|
|
||||||
public void setOrder(int order) {
|
public void setOrder(int order) {
|
||||||
|
@ -42,8 +44,15 @@ public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordere
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
|
if (this.order != null) {
|
||||||
return this.order;
|
return this.order;
|
||||||
}
|
}
|
||||||
|
Advice advice = getAdvice();
|
||||||
|
if (advice instanceof Ordered) {
|
||||||
|
return ((Ordered) advice).getOrder();
|
||||||
|
}
|
||||||
|
return Ordered.LOWEST_PRECEDENCE;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPerInstance() {
|
public boolean isPerInstance() {
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue