Browse Source

Consistent use of LinkedHashSet for interfaces (since interface order may matter in subtle cases)

(cherry picked from commit 6f9d7da)
pull/689/head
Juergen Hoeller 11 years ago
parent
commit
1341fd4e73
  1. 2
      spring-aop/src/main/java/org/springframework/aop/IntroductionInfo.java
  2. 14
      spring-aop/src/main/java/org/springframework/aop/aspectj/DeclareParentsAdvisor.java
  3. 6
      spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java
  4. 23
      spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java
  5. 16
      spring-aop/src/main/java/org/springframework/aop/support/IntroductionInfoSupport.java

2
spring-aop/src/main/java/org/springframework/aop/IntroductionInfo.java

@ -34,6 +34,6 @@ public interface IntroductionInfo {
* Return the additional interfaces introduced by this Advisor or Advice. * Return the additional interfaces introduced by this Advisor or Advice.
* @return the introduced interfaces * @return the introduced interfaces
*/ */
Class[] getInterfaces(); Class<?>[] getInterfaces();
} }

14
spring-aop/src/main/java/org/springframework/aop/aspectj/DeclareParentsAdvisor.java

@ -34,7 +34,7 @@ import org.springframework.aop.support.DelegatingIntroductionInterceptor;
*/ */
public class DeclareParentsAdvisor implements IntroductionAdvisor { public class DeclareParentsAdvisor implements IntroductionAdvisor {
private final Class introducedInterface; private final Class<?> introducedInterface;
private final ClassFilter typePatternClassFilter; private final ClassFilter typePatternClassFilter;
@ -47,7 +47,7 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* @param typePattern type pattern the introduction is restricted to * @param typePattern type pattern the introduction is restricted to
* @param defaultImpl the default implementation class * @param defaultImpl the default implementation class
*/ */
public DeclareParentsAdvisor(Class interfaceType, String typePattern, Class defaultImpl) { public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> defaultImpl) {
this(interfaceType, typePattern, defaultImpl, this(interfaceType, typePattern, defaultImpl,
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType)); new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
} }
@ -58,7 +58,7 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* @param typePattern type pattern the introduction is restricted to * @param typePattern type pattern the introduction is restricted to
* @param delegateRef the delegate implementation object * @param delegateRef the delegate implementation object
*/ */
public DeclareParentsAdvisor(Class interfaceType, String typePattern, Object delegateRef) { public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Object delegateRef) {
this(interfaceType, typePattern, delegateRef.getClass(), this(interfaceType, typePattern, delegateRef.getClass(),
new DelegatingIntroductionInterceptor(delegateRef)); new DelegatingIntroductionInterceptor(delegateRef));
} }
@ -71,13 +71,13 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* @param implementationClass implementation class * @param implementationClass implementation class
* @param advice delegation advice * @param advice delegation advice
*/ */
private DeclareParentsAdvisor(Class interfaceType, String typePattern, Class implementationClass, Advice advice) { private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> implementationClass, Advice advice) {
this.introducedInterface = interfaceType; this.introducedInterface = interfaceType;
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern); ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
// Excludes methods implemented. // Excludes methods implemented.
ClassFilter exclusion = new ClassFilter() { ClassFilter exclusion = new ClassFilter() {
public boolean matches(Class clazz) { public boolean matches(Class<?> clazz) {
return !(introducedInterface.isAssignableFrom(clazz)); return !(introducedInterface.isAssignableFrom(clazz));
} }
}; };
@ -103,8 +103,8 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
return this.advice; return this.advice;
} }
public Class[] getInterfaces() { public Class<?>[] getInterfaces() {
return new Class[] {this.introducedInterface}; return new Class<?>[] {this.introducedInterface};
} }
} }

6
spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 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.
@ -19,7 +19,7 @@ package org.springframework.aop.support;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.HashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -215,7 +215,7 @@ public abstract class AopUtils {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
} }
Set<Class> classes = new HashSet<Class>(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); Set<Class> classes = new LinkedHashSet<Class>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass); classes.add(targetClass);
for (Class<?> clazz : classes) { for (Class<?> clazz : classes) {
Method[] methods = clazz.getMethods(); Method[] methods = clazz.getMethods();

23
spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 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.
@ -17,7 +17,7 @@
package org.springframework.aop.support; package org.springframework.aop.support;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashSet; import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
import org.aopalliance.aop.Advice; import org.aopalliance.aop.Advice;
@ -43,7 +43,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
private final Advice advice; private final Advice advice;
private final Set<Class> interfaces = new HashSet<Class>(); private final Set<Class> interfaces = new LinkedHashSet<Class>();
private int order = Integer.MAX_VALUE; private int order = Integer.MAX_VALUE;
@ -68,11 +68,11 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
Assert.notNull(advice, "Advice must not be null"); Assert.notNull(advice, "Advice must not be null");
this.advice = advice; this.advice = advice;
if (introductionInfo != null) { if (introductionInfo != null) {
Class[] introducedInterfaces = introductionInfo.getInterfaces(); Class<?>[] introducedInterfaces = introductionInfo.getInterfaces();
if (introducedInterfaces.length == 0) { if (introducedInterfaces.length == 0) {
throw new IllegalArgumentException("IntroductionAdviceSupport implements no interfaces"); throw new IllegalArgumentException("IntroductionAdviceSupport implements no interfaces");
} }
for (Class ifc : introducedInterfaces) { for (Class<?> ifc : introducedInterfaces) {
addInterface(ifc); addInterface(ifc);
} }
} }
@ -83,7 +83,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
* @param advice the Advice to apply * @param advice the Advice to apply
* @param intf the interface to introduce * @param intf the interface to introduce
*/ */
public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class intf) { public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> intf) {
Assert.notNull(advice, "Advice must not be null"); Assert.notNull(advice, "Advice must not be null");
this.advice = advice; this.advice = advice;
addInterface(intf); addInterface(intf);
@ -94,7 +94,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
* Add the specified interface to the list of interfaces to introduce. * Add the specified interface to the list of interfaces to introduce.
* @param intf the interface to introduce * @param intf the interface to introduce
*/ */
public void addInterface(Class intf) { public void addInterface(Class<?> intf) {
Assert.notNull(intf, "Interface must not be null"); Assert.notNull(intf, "Interface must not be null");
if (!intf.isInterface()) { if (!intf.isInterface()) {
throw new IllegalArgumentException("Specified class [" + intf.getName() + "] must be an interface"); throw new IllegalArgumentException("Specified class [" + intf.getName() + "] must be an interface");
@ -102,12 +102,13 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
this.interfaces.add(intf); this.interfaces.add(intf);
} }
public Class[] getInterfaces() { public Class<?>[] getInterfaces() {
return this.interfaces.toArray(new Class[this.interfaces.size()]); return this.interfaces.toArray(new Class<?>[this.interfaces.size()]);
} }
@Override
public void validateInterfaces() throws IllegalArgumentException { public void validateInterfaces() throws IllegalArgumentException {
for (Class ifc : this.interfaces) { for (Class<?> ifc : this.interfaces) {
if (this.advice instanceof DynamicIntroductionAdvice && if (this.advice instanceof DynamicIntroductionAdvice &&
!((DynamicIntroductionAdvice) this.advice).implementsInterface(ifc)) { !((DynamicIntroductionAdvice) this.advice).implementsInterface(ifc)) {
throw new IllegalArgumentException("DynamicIntroductionAdvice [" + this.advice + "] " + throw new IllegalArgumentException("DynamicIntroductionAdvice [" + this.advice + "] " +
@ -138,7 +139,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
return this; return this;
} }
public boolean matches(Class clazz) { public boolean matches(Class<?> clazz) {
return true; return true;
} }

16
spring-aop/src/main/java/org/springframework/aop/support/IntroductionInfoSupport.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2014 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.
@ -20,7 +20,7 @@ import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -43,7 +43,7 @@ import org.springframework.util.ClassUtils;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class IntroductionInfoSupport implements IntroductionInfo, Serializable { public class IntroductionInfoSupport implements IntroductionInfo, Serializable {
protected final Set<Class> publishedInterfaces = new HashSet<Class>(); protected final Set<Class> publishedInterfaces = new LinkedHashSet<Class>();
private transient Map<Method, Boolean> rememberedMethods = new ConcurrentHashMap<Method, Boolean>(32); private transient Map<Method, Boolean> rememberedMethods = new ConcurrentHashMap<Method, Boolean>(32);
@ -55,12 +55,12 @@ public class IntroductionInfoSupport implements IntroductionInfo, Serializable {
* <p>Does nothing if the interface is not implemented by the delegate. * <p>Does nothing if the interface is not implemented by the delegate.
* @param intf the interface to suppress * @param intf the interface to suppress
*/ */
public void suppressInterface(Class intf) { public void suppressInterface(Class<?> intf) {
this.publishedInterfaces.remove(intf); this.publishedInterfaces.remove(intf);
} }
public Class[] getInterfaces() { public Class<?>[] getInterfaces() {
return this.publishedInterfaces.toArray(new Class[this.publishedInterfaces.size()]); return this.publishedInterfaces.toArray(new Class<?>[this.publishedInterfaces.size()]);
} }
/** /**
@ -68,8 +68,8 @@ public class IntroductionInfoSupport implements IntroductionInfo, Serializable {
* @param ifc the interface to check * @param ifc the interface to check
* @return whether the interface is part of this introduction * @return whether the interface is part of this introduction
*/ */
public boolean implementsInterface(Class ifc) { public boolean implementsInterface(Class<?> ifc) {
for (Class pubIfc : this.publishedInterfaces) { for (Class<?> pubIfc : this.publishedInterfaces) {
if (ifc.isInterface() && ifc.isAssignableFrom(pubIfc)) { if (ifc.isInterface() && ifc.isAssignableFrom(pubIfc)) {
return true; return true;
} }

Loading…
Cancel
Save