Distinguish between different bridge method types

Add BridgeMethodResolver#isJava6VisibilityBridgeMethodPair to
distinguish between (a) bridge methods introduced in Java 6 to
compensate for inheriting public methods from non-public superclasses
and (b) bridge methods that have existed since Java 5 to accommodate
return type covariance and generic parameters.

In the former case, annotations should be looked up from the original
bridged method (SPR-7900).  In the latter, the annotation should be
looked up against the bridge method itself (SPR-8660).

As noted in the Javadoc for the new method, see
http://stas-blogspot.blogspot.com/2010/03/java-bridge-methods-explained.html
for a useful description of the various types of bridge methods, as
well as http://bugs.sun.com/view_bug.do?bug_id=6342411, the bug fixed in
Java 6 resulting in the introduction of 'visibility bridge methods'.

Issue: SPR-8660, SPR-7900
This commit is contained in:
Chris Beams
2011-10-10 05:40:21 +00:00
parent 6248135a4f
commit 980c15d578
3 changed files with 87 additions and 6 deletions

View File

@@ -16,6 +16,9 @@
package org.springframework.beans.factory.annotation;
import static org.springframework.core.BridgeMethodResolver.findBridgedMethod;
import static org.springframework.core.BridgeMethodResolver.isJava6VisibilityBridgeMethodPair;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
@@ -35,7 +38,6 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
@@ -50,7 +52,6 @@ import org.springframework.beans.factory.config.InstantiationAwareBeanPostProces
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
@@ -342,7 +343,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
}
}
for (Method method : targetClass.getDeclaredMethods()) {
Annotation annotation = findAutowiredAnnotation(method);
Method bridgedMethod = findBridgedMethod(method);
Annotation annotation = isJava6VisibilityBridgeMethodPair(method, bridgedMethod) ?
findAutowiredAnnotation(bridgedMethod) :
findAutowiredAnnotation(method);
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
@@ -370,9 +374,6 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
private Annotation findAutowiredAnnotation(AccessibleObject ao) {
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
if (ao instanceof Method) {
ao = BridgeMethodResolver.findBridgedMethod((Method) ao);
}
Annotation annotation = ao.getAnnotation(type);
if (annotation != null) {
return annotation;