diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 406d02d5e5..90427f18ce 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -271,6 +271,19 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean Constructor defaultConstructor = null; for (Constructor candidate : rawCandidates) { AnnotationAttributes ann = findAutowiredAnnotation(candidate); + if (ann == null) { + Class userClass = ClassUtils.getUserClass(beanClass); + if (userClass != beanClass) { + try { + Constructor superCtor = + userClass.getDeclaredConstructor(candidate.getParameterTypes()); + ann = findAutowiredAnnotation(superCtor); + } + catch (NoSuchMethodException ex) { + // Simply proceed, no equivalent superclass constructor found... + } + } + } if (ann != null) { if (requiredConstructor != null) { throw new BeanCreationException(beanName, diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java index 61600eca89..8174725a04 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/AutowiredConfigurationTests.java @@ -23,7 +23,6 @@ import javax.inject.Provider; import org.junit.Test; -import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -90,7 +89,7 @@ public class AutowiredConfigurationTests { } @Test - public void testAutowiredConfigurationConstructorsAreSupported() { + public void testAutowiredSingleConstructorSupported() { DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); new XmlBeanDefinitionReader(factory).loadBeanDefinitions( new ClassPathResource("annotation-config.xml", AutowiredConstructorConfig.class)); @@ -98,8 +97,19 @@ public class AutowiredConfigurationTests { ctx.registerBeanDefinition("config1", new RootBeanDefinition(AutowiredConstructorConfig.class)); ctx.registerBeanDefinition("config2", new RootBeanDefinition(ColorConfig.class)); ctx.refresh(); - assertSame(ctx.getBean(AutowiredConstructorConfig.class).colour, - ctx.getBean(Colour.class)); + assertSame(ctx.getBean(AutowiredConstructorConfig.class).colour, ctx.getBean(Colour.class)); + } + + @Test + public void testAutowiredAnnotatedConstructorSupported() { + DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); + new XmlBeanDefinitionReader(factory).loadBeanDefinitions( + new ClassPathResource("annotation-config.xml", MultipleConstructorConfig.class)); + GenericApplicationContext ctx = new GenericApplicationContext(factory); + ctx.registerBeanDefinition("config1", new RootBeanDefinition(MultipleConstructorConfig.class)); + ctx.registerBeanDefinition("config2", new RootBeanDefinition(ColorConfig.class)); + ctx.refresh(); + assertSame(ctx.getBean(MultipleConstructorConfig.class).colour, ctx.getBean(Colour.class)); } @Test @@ -223,13 +233,29 @@ public class AutowiredConfigurationTests { Colour colour; - @Autowired + // @Autowired AutowiredConstructorConfig(Colour colour) { this.colour = colour; } } + @Configuration + static class MultipleConstructorConfig { + + Colour colour; + + @Autowired + MultipleConstructorConfig(Colour colour) { + this.colour = colour; + } + + MultipleConstructorConfig(String test) { + this.colour = new Colour(test); + } + } + + @Configuration static class ColorConfig {