Sort candidate @AspectJ methods deterministically

Update the ReflectiveAspectJAdvisorFactory class to sort candidate
AOP methods based on their annotation first and method name second.

Prior to this the order of aspects created from annotated methods
could differ depending on the underling JVM, as first noticed under
JDK7 in SPR-9729.

 - ConvertingComparator and InstanceComparator have been introduced in
   support of this change, per SPR-9730.

 - A shared static INSTANCE field has been added to ComparableComparator
   to avoid unnecessary instantiation costs within ConvertingComparator
   as well as to prevent generics warnings during certain caller
   scenarios.

Issue: SPR-9729, SPR-9730
This commit is contained in:
Phillip Webb
2012-08-27 13:24:58 -07:00
committed by Chris Beams
parent 719a9e120d
commit 77c9321967
6 changed files with 457 additions and 35 deletions

View File

@@ -39,7 +39,11 @@ import org.aspectj.lang.annotation.DeclareParents;
import org.aspectj.lang.annotation.DeclarePrecedence;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor;
import org.springframework.aop.framework.Advised;
@@ -65,9 +69,13 @@ import test.beans.TestBean;
*
* @author Rod Johnson
* @author Chris Beams
* @author Phillip Webb
*/
public abstract class AbstractAspectJAdvisorFactoryTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
/**
* To be overridden by concrete test subclasses.
* @return the fixture
@@ -571,31 +579,22 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
@Test
public void testFailureWithoutExplicitDeclarePrecedence() {
TestBean target = new TestBean();
ITestBean itb = (ITestBean) createProxy(target,
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new NoDeclarePrecedenceShouldFail(), "someBean")),
ITestBean.class);
try {
itb.getAge();
fail();
}
catch (IllegalStateException ex) {
// expected
}
MetadataAwareAspectInstanceFactory aspectInstanceFactory = new SingletonMetadataAwareAspectInstanceFactory(
new NoDeclarePrecedenceShouldFail(), "someBean");
ITestBean itb = (ITestBean) createProxy(target,
getFixture().getAdvisors(aspectInstanceFactory), ITestBean.class);
itb.getAge();
}
@Test
public void testDeclarePrecedenceNotSupported() {
TestBean target = new TestBean();
try {
createProxy(target,
getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(
new DeclarePrecedenceShouldSucceed(),"someBean")),
ITestBean.class);
fail();
}
catch (IllegalArgumentException ex) {
// Not supported in 2.0
}
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("DeclarePrecendence not presently supported in Spring AOP");
MetadataAwareAspectInstanceFactory aspectInstanceFactory = new SingletonMetadataAwareAspectInstanceFactory(
new DeclarePrecedenceShouldSucceed(), "someBean");
createProxy(target, getFixture().getAdvisors(aspectInstanceFactory),
ITestBean.class);
}
/** Not supported in 2.0!