Skip to content

Commit 29abca5

Browse files
committed
Explicit exclusion of bridge methods in annotation post-processors (for Java 8 compatibility)
Issue: SPR-12187 (cherry picked from commit f4219ca)
1 parent 60d5ff8 commit 29abca5

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

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

+9-4
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,15 @@ private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
358358
}
359359
}
360360
for (Method method : targetClass.getDeclaredMethods()) {
361+
AnnotationAttributes ann = null;
361362
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
362-
AnnotationAttributes annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ?
363-
findAutowiredAnnotation(bridgedMethod) : findAutowiredAnnotation(method);
364-
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
363+
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
364+
ann = findAutowiredAnnotation(bridgedMethod);
365+
}
366+
else if (!method.isBridge()) {
367+
ann = findAutowiredAnnotation(method);
368+
}
369+
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
365370
if (Modifier.isStatic(method.getModifiers())) {
366371
if (logger.isWarnEnabled()) {
367372
logger.warn("Autowired annotation is not supported on static methods: " + method);
@@ -373,7 +378,7 @@ private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
373378
logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
374379
}
375380
}
376-
boolean required = determineRequiredStatus(annotation);
381+
boolean required = determineRequiredStatus(ann);
377382
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
378383
currElements.add(new AutowiredMethodElement(method, required, pd));
379384
}

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

+54
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.lang.reflect.Proxy;
2727
import java.util.List;
2828
import java.util.Map;
29+
import java.util.concurrent.Callable;
2930

3031
import org.junit.Test;
3132
import org.mockito.Mockito;
@@ -1734,6 +1735,18 @@ public void testCircularTypeReference() {
17341735
assertSame(bf.getBean(StockMovementDaoImpl.class), service.stockMovementDao);
17351736
}
17361737

1738+
@Test
1739+
public void testBridgeMethodHandling() {
1740+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
1741+
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
1742+
bpp.setBeanFactory(bf);
1743+
bf.addBeanPostProcessor(bpp);
1744+
bf.registerBeanDefinition("bean1", new RootBeanDefinition(MyCallable.class));
1745+
bf.registerBeanDefinition("bean2", new RootBeanDefinition(SecondCallable.class));
1746+
bf.registerBeanDefinition("bean3", new RootBeanDefinition(FooBar.class));
1747+
assertNotNull(bf.getBean(FooBar.class));
1748+
}
1749+
17371750

17381751
public static class ResourceInjectionBean {
17391752

@@ -2729,4 +2742,45 @@ public static class StockServiceImpl {
27292742
private StockMovementDao<StockMovement> stockMovementDao;
27302743
}
27312744

2745+
2746+
public static class MyCallable implements Callable<Thread> {
2747+
2748+
@Override
2749+
public Thread call() throws Exception {
2750+
return null;
2751+
}
2752+
}
2753+
2754+
2755+
public static class SecondCallable implements Callable<Thread>{
2756+
2757+
@Override
2758+
public Thread call() throws Exception {
2759+
return null;
2760+
}
2761+
}
2762+
2763+
2764+
public static abstract class Foo<T extends Runnable, RT extends Callable<T>> {
2765+
2766+
private RT obj;
2767+
2768+
protected void setObj(RT obj) {
2769+
if (this.obj != null) {
2770+
throw new IllegalStateException("Already called");
2771+
}
2772+
this.obj = obj;
2773+
}
2774+
}
2775+
2776+
2777+
public static class FooBar extends Foo<Thread, MyCallable> {
2778+
2779+
@Override
2780+
@Autowired
2781+
public void setObj(MyCallable obj) {
2782+
super.setObj(obj);
2783+
}
2784+
}
2785+
27322786
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ private InjectionMetadata findPersistenceMetadata(String beanName, final Class<?
402402
for (Method method : targetClass.getDeclaredMethods()) {
403403
PersistenceContext pc = method.getAnnotation(PersistenceContext.class);
404404
PersistenceUnit pu = method.getAnnotation(PersistenceUnit.class);
405-
if ((pc != null || pu != null) &&
405+
if ((pc != null || pu != null) && !method.isBridge() &&
406406
method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
407407
if (Modifier.isStatic(method.getModifiers())) {
408408
throw new IllegalStateException("Persistence annotations are not supported on static methods");

0 commit comments

Comments
 (0)