Browse Source

Explicit exclusion of bridge methods in annotation post-processors (for Java 8 compatibility)

Issue: SPR-12187
(cherry picked from commit f4219ca)
pull/642/head
Juergen Hoeller 11 years ago
parent
commit
29abca5399
  1. 13
      spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
  2. 54
      spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java
  3. 2
      spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java

13
spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java

@ -358,10 +358,15 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean @@ -358,10 +358,15 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
}
}
for (Method method : targetClass.getDeclaredMethods()) {
AnnotationAttributes ann = null;
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
AnnotationAttributes annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ?
findAutowiredAnnotation(bridgedMethod) : findAutowiredAnnotation(method);
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
ann = findAutowiredAnnotation(bridgedMethod);
}
else if (!method.isBridge()) {
ann = findAutowiredAnnotation(method);
}
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
@ -373,7 +378,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean @@ -373,7 +378,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
}
}
boolean required = determineRequiredStatus(annotation);
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
currElements.add(new AutowiredMethodElement(method, required, pd));
}

54
spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java

@ -26,6 +26,7 @@ import java.lang.reflect.Method; @@ -26,6 +26,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import org.junit.Test;
import org.mockito.Mockito;
@ -1734,6 +1735,18 @@ public class AutowiredAnnotationBeanPostProcessorTests { @@ -1734,6 +1735,18 @@ public class AutowiredAnnotationBeanPostProcessorTests {
assertSame(bf.getBean(StockMovementDaoImpl.class), service.stockMovementDao);
}
@Test
public void testBridgeMethodHandling() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp);
bf.registerBeanDefinition("bean1", new RootBeanDefinition(MyCallable.class));
bf.registerBeanDefinition("bean2", new RootBeanDefinition(SecondCallable.class));
bf.registerBeanDefinition("bean3", new RootBeanDefinition(FooBar.class));
assertNotNull(bf.getBean(FooBar.class));
}
public static class ResourceInjectionBean {
@ -2729,4 +2742,45 @@ public class AutowiredAnnotationBeanPostProcessorTests { @@ -2729,4 +2742,45 @@ public class AutowiredAnnotationBeanPostProcessorTests {
private StockMovementDao<StockMovement> stockMovementDao;
}
public static class MyCallable implements Callable<Thread> {
@Override
public Thread call() throws Exception {
return null;
}
}
public static class SecondCallable implements Callable<Thread>{
@Override
public Thread call() throws Exception {
return null;
}
}
public static abstract class Foo<T extends Runnable, RT extends Callable<T>> {
private RT obj;
protected void setObj(RT obj) {
if (this.obj != null) {
throw new IllegalStateException("Already called");
}
this.obj = obj;
}
}
public static class FooBar extends Foo<Thread, MyCallable> {
@Override
@Autowired
public void setObj(MyCallable obj) {
super.setObj(obj);
}
}
}

2
spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java

@ -402,7 +402,7 @@ public class PersistenceAnnotationBeanPostProcessor @@ -402,7 +402,7 @@ public class PersistenceAnnotationBeanPostProcessor
for (Method method : targetClass.getDeclaredMethods()) {
PersistenceContext pc = method.getAnnotation(PersistenceContext.class);
PersistenceUnit pu = method.getAnnotation(PersistenceUnit.class);
if ((pc != null || pu != null) &&
if ((pc != null || pu != null) && !method.isBridge() &&
method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("Persistence annotations are not supported on static methods");

Loading…
Cancel
Save