Skip to content

Commit 2c3c383

Browse files
committed
Consistently ignore bridge method on generated subclass for visibility purposes
Closes gh-33030
1 parent c38e989 commit 2c3c383

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java

+36
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.junit.jupiter.api.Test;
2727

2828
import org.springframework.beans.factory.BeanFactory;
29+
import org.springframework.beans.factory.InitializingBean;
2930
import org.springframework.beans.factory.ObjectFactory;
3031
import org.springframework.beans.factory.annotation.Autowired;
3132
import org.springframework.beans.factory.annotation.Value;
@@ -43,6 +44,7 @@
4344
import org.springframework.core.annotation.AliasFor;
4445
import org.springframework.core.io.ClassPathResource;
4546
import org.springframework.core.io.Resource;
47+
import org.springframework.util.Assert;
4648

4749
import static org.assertj.core.api.Assertions.assertThat;
4850

@@ -183,6 +185,14 @@ void testValueInjectionWithProviderMethodArguments() {
183185
context.close();
184186
}
185187

188+
@Test
189+
void testValueInjectionWithAccidentalAutowiredAnnotations() {
190+
AnnotationConfigApplicationContext context =
191+
new AnnotationConfigApplicationContext(ValueConfigWithAccidentalAutowiredAnnotations.class);
192+
doTestValueInjection(context);
193+
context.close();
194+
}
195+
186196
private void doTestValueInjection(BeanFactory context) {
187197
System.clearProperty("myProp");
188198

@@ -494,6 +504,32 @@ public TestBean testBean2(@Value("#{systemProperties[myProp]}") Provider<String>
494504
}
495505

496506

507+
@Configuration
508+
static class ValueConfigWithAccidentalAutowiredAnnotations implements InitializingBean {
509+
510+
boolean invoked;
511+
512+
@Override
513+
public void afterPropertiesSet() {
514+
Assert.state(!invoked, "Factory method must not get invoked on startup");
515+
}
516+
517+
@Bean @Scope("prototype")
518+
@Autowired
519+
public TestBean testBean(@Value("#{systemProperties[myProp]}") Provider<String> name) {
520+
invoked = true;
521+
return new TestBean(name.get());
522+
}
523+
524+
@Bean @Scope("prototype")
525+
@Autowired
526+
public TestBean testBean2(@Value("#{systemProperties[myProp]}") Provider<String> name2) {
527+
invoked = true;
528+
return new TestBean(name2.get());
529+
}
530+
}
531+
532+
497533
@Configuration
498534
static class PropertiesConfig {
499535

spring-core/src/main/java/org/springframework/core/BridgeMethodResolver.java

+5
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,13 @@ private static Method searchForMatch(Class<?> type, Method bridgeMethod) {
276276
*/
277277
public static boolean isVisibilityBridgeMethodPair(Method bridgeMethod, Method bridgedMethod) {
278278
if (bridgeMethod == bridgedMethod) {
279+
// Same method: for common purposes, return true to proceed as if it was a visibility bridge.
279280
return true;
280281
}
282+
if (ClassUtils.getUserClass(bridgeMethod.getDeclaringClass()) != bridgeMethod.getDeclaringClass()) {
283+
// Method on generated subclass: return false to consistently ignore it for visibility purposes.
284+
return false;
285+
}
281286
return (bridgeMethod.getReturnType().equals(bridgedMethod.getReturnType()) &&
282287
bridgeMethod.getParameterCount() == bridgedMethod.getParameterCount() &&
283288
Arrays.equals(bridgeMethod.getParameterTypes(), bridgedMethod.getParameterTypes()));

0 commit comments

Comments
 (0)