Allow for specific instance-based match to override factory method signature match

Issue: SPR-11046
This commit is contained in:
Juergen Hoeller
2013-10-30 22:01:32 +01:00
parent ac7e27b785
commit f9584184ef
2 changed files with 122 additions and 21 deletions

View File

@@ -16,8 +16,10 @@
package org.springframework.context.annotation;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver;
@@ -31,9 +33,21 @@ import static org.junit.Assert.*;
/**
* @author Chris Beams
* @author Juergen Hoeller
*/
public class ConfigurationClassPostProcessorTests {
private DefaultListableBeanFactory beanFactory;
@Before
public void setUp() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
QualifierAnnotationAutowireCandidateResolver acr = new QualifierAnnotationAutowireCandidateResolver();
acr.setBeanFactory(bf);
bf.setAutowireCandidateResolver(acr);
this.beanFactory = bf;
}
/**
* Enhanced {@link Configuration} classes are only necessary for respecting
* certain bean semantics, like singleton-scoping, scoped proxies, etc.
@@ -45,7 +59,6 @@ public class ConfigurationClassPostProcessorTests {
*/
@Test
public void testEnhancementIsPresentBecauseSingletonSemanticsAreRespected() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
@@ -60,7 +73,6 @@ public class ConfigurationClassPostProcessorTests {
*/
@Test
public void testAlreadyLoadedConfigurationClasses() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerBeanDefinition("unloadedConfig",
new RootBeanDefinition(UnloadedConfig.class.getName(), null, null));
beanFactory.registerBeanDefinition("loadedConfig", new RootBeanDefinition(LoadedConfig.class));
@@ -76,7 +88,6 @@ public class ConfigurationClassPostProcessorTests {
*/
@Test
public void testPostProcessorIntrospectsInheritedDefinitionsCorrectly() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class));
beanFactory.registerBeanDefinition("parent", new RootBeanDefinition(TestBean.class));
beanFactory.registerBeanDefinition("child", new ChildBeanDefinition("parent"));
@@ -89,7 +100,6 @@ public class ConfigurationClassPostProcessorTests {
@Test
public void testPostProcessorOverridesNonApplicationBeanDefinitions() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
rbd.setRole(RootBeanDefinition.ROLE_SUPPORT);
beanFactory.registerBeanDefinition("bar", rbd);
@@ -103,7 +113,6 @@ public class ConfigurationClassPostProcessorTests {
@Test
public void testPostProcessorDoesNotOverrideRegularBeanDefinitions() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
rbd.setResource(new DescriptiveResource("XML or something"));
beanFactory.registerBeanDefinition("bar", rbd);
@@ -137,32 +146,62 @@ public class ConfigurationClassPostProcessorTests {
@Test
public void testGenericsBasedInjection() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp);
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
RootBeanDefinition bd = new RootBeanDefinition(RepositoryInjectionBean.class);
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
bf.registerBeanDefinition("annotatedBean", bd);
bf.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
beanFactory.registerBeanDefinition("annotatedBean", bd);
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryConfiguration.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(bf);
pp.postProcessBeanFactory(beanFactory);
RepositoryInjectionBean bean = (RepositoryInjectionBean) bf.getBean("annotatedBean");
assertSame(bf.getBean("stringRepo"), bean.stringRepository);
assertSame(bf.getBean("integerRepo"), bean.integerRepository);
RepositoryInjectionBean bean = (RepositoryInjectionBean) beanFactory.getBean("annotatedBean");
assertSame(beanFactory.getBean("stringRepo"), bean.stringRepository);
assertSame(beanFactory.getBean("integerRepo"), bean.integerRepository);
}
@Test
public void testGenericsBasedInjectionWithImplTypeAtInjectionPoint() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
RootBeanDefinition bd = new RootBeanDefinition(SpecificRepositoryInjectionBean.class);
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
beanFactory.registerBeanDefinition("annotatedBean", bd);
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(SpecificRepositoryConfiguration.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
beanFactory.preInstantiateSingletons();
SpecificRepositoryInjectionBean bean = (SpecificRepositoryInjectionBean) beanFactory.getBean("annotatedBean");
assertSame(beanFactory.getBean("genericRepo"), bean.genericRepository);
}
@Test
public void testGenericsBasedInjectionWithFactoryBean() {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(bpp);
RootBeanDefinition bd = new RootBeanDefinition(RepositoryFactoryBeanInjectionBean.class);
bd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
beanFactory.registerBeanDefinition("annotatedBean", bd);
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RepositoryFactoryBeanConfiguration.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
beanFactory.preInstantiateSingletons();
RepositoryFactoryBeanInjectionBean bean = (RepositoryFactoryBeanInjectionBean) beanFactory.getBean("annotatedBean");
assertSame(beanFactory.getBean("&repoFactoryBean"), bean.repositoryFactoryBean);
}
@Test
public void testGenericsBasedInjectionWithRawMatch() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
bf.registerBeanDefinition("configClass", new RootBeanDefinition(RawMatchingConfiguration.class));
beanFactory.registerBeanDefinition("configClass", new RootBeanDefinition(RawMatchingConfiguration.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(bf);
pp.postProcessBeanFactory(beanFactory);
assertSame(bf.getBean("repo"), bf.getBean("repoConsumer"));
assertSame(beanFactory.getBean("repo"), beanFactory.getBean("repoConsumer"));
}
@@ -215,6 +254,29 @@ public class ConfigurationClassPostProcessorTests {
}
public static class GenericRepository<T> extends Repository<T> {
}
public static class RepositoryFactoryBean<T> implements FactoryBean<T> {
@Override
public T getObject() {
throw new IllegalStateException();
}
@Override
public Class<?> getObjectType() {
return Object.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
public static class RepositoryInjectionBean {
@Autowired
@@ -240,6 +302,40 @@ public class ConfigurationClassPostProcessorTests {
}
public static class SpecificRepositoryInjectionBean {
@Autowired
public GenericRepository<?> genericRepository;
}
@Configuration
public static class SpecificRepositoryConfiguration {
@Bean
public Repository<Object> genericRepo() {
return new GenericRepository<Object>();
}
}
public static class RepositoryFactoryBeanInjectionBean {
@Autowired
public RepositoryFactoryBean<?> repositoryFactoryBean;
}
@Configuration
public static class RepositoryFactoryBeanConfiguration {
@Bean
public RepositoryFactoryBean<Object> repoFactoryBean() {
return new RepositoryFactoryBean<>();
}
}
@Configuration
public static class RawMatchingConfiguration {