Early resolution of unique factory methods in configuration classes

Includes consistent bean class resolution in the enhancement step as well as general reflection optimizations for user-declared methods.

Closes gh-22420
This commit is contained in:
Juergen Hoeller
2019-03-12 17:17:24 +01:00
parent a35adc6ea6
commit 40c62139ae
10 changed files with 271 additions and 142 deletions

View File

@@ -97,6 +97,19 @@ public class ConfigurationClassPostProcessorTests {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("config")).hasBeanClass());
Foo foo = beanFactory.getBean("foo", Foo.class);
Bar bar = beanFactory.getBean("bar", Bar.class);
assertSame(foo, bar.foo);
assertTrue(Arrays.asList(beanFactory.getDependentBeans("foo")).contains("bar"));
}
@Test
public void enhancementIsPresentBecauseSingletonSemanticsAreRespectedUsingAsm() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(SingletonBeanConfig.class.getName()));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("config")).hasBeanClass());
Foo foo = beanFactory.getBean("foo", Foo.class);
Bar bar = beanFactory.getBean("bar", Bar.class);
assertSame(foo, bar.foo);
@@ -108,6 +121,44 @@ public class ConfigurationClassPostProcessorTests {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(NonEnhancedSingletonBeanConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("config")).hasBeanClass());
Foo foo = beanFactory.getBean("foo", Foo.class);
Bar bar = beanFactory.getBean("bar", Bar.class);
assertNotSame(foo, bar.foo);
}
@Test
public void enhancementIsNotPresentForProxyBeanMethodsFlagSetToFalseUsingAsm() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(NonEnhancedSingletonBeanConfig.class.getName()));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("config")).hasBeanClass());
Foo foo = beanFactory.getBean("foo", Foo.class);
Bar bar = beanFactory.getBean("bar", Bar.class);
assertNotSame(foo, bar.foo);
}
@Test
public void enhancementIsNotPresentForStaticMethods() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(StaticSingletonBeanConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("config")).hasBeanClass());
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("foo")).hasBeanClass());
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("bar")).hasBeanClass());
Foo foo = beanFactory.getBean("foo", Foo.class);
Bar bar = beanFactory.getBean("bar", Bar.class);
assertNotSame(foo, bar.foo);
}
@Test
public void enhancementIsNotPresentForStaticMethodsUsingAsm() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(StaticSingletonBeanConfig.class.getName()));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.postProcessBeanFactory(beanFactory);
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("config")).hasBeanClass());
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("foo")).hasBeanClass());
assertTrue(((RootBeanDefinition) beanFactory.getBeanDefinition("bar")).hasBeanClass());
Foo foo = beanFactory.getBean("foo", Foo.class);
Bar bar = beanFactory.getBean("bar", Bar.class);
assertNotSame(foo, bar.foo);
@@ -1090,6 +1141,18 @@ public class ConfigurationClassPostProcessorTests {
}
}
@Configuration
static class StaticSingletonBeanConfig {
public static @Bean Foo foo() {
return new Foo();
}
public static @Bean Bar bar() {
return new Bar(foo());
}
}
@Configuration
@Order(2)
static class OverridingSingletonBeanConfig {