Description
Joshua Hoke opened SPR-14234 and commented
When you implement the BeanDefinitionRegistryPostProcessor interface on your @Configuration
class, it causes the class to be instantiated as a singleton bean before the Spring internal ConfigurationAnnotationProcessor has replaced it with the CGLIB-enhanced subclass in the bean definition.
This was found when using the AnnotationConfigWebApplicationContext contextClass in a Tomcat WAR. We initially saw it with Spring 3.2.8, but it still seems to be a problem in 4.2.5.
This breaks the following behavior described in the documentation:
@Bean
Methods in@Configuration
ClassesTypically,
@Bean
methods are declared within@Configuration
classes. In this case, bean methods may reference other@Bean
methods in the same class by calling them directly. This ensures that references between beans are strongly typed and navigable. Such so-called 'inter-bean references' are guaranteed to respect scoping and AOP semantics, just like getBean() lookups would. These are the semantics known from the original 'Spring JavaConfig' project which require CGLIB subclassing of each such configuration class at runtime. As a consequence,@Configuration
classes and their factory methods must not be marked as final or private in this mode. For example:
@Configuration
public class AppConfig {
@Bean
public FooService fooService() {
return new FooService(fooRepository());
}
@Bean
public FooRepository fooRepository() {
return new JdbcFooRepository(dataSource());
}
// ...
}
Instead, fooRepository() in this example will end up running multiple times because the bean instance is the actual @Configuration
class instead of the enhanced subclass that caches singleton beans.
Desired behavior:
Either this should work as documented (which could be a breaking change if anyone was depending on this particular bug invoking methods in @Configuration
more than once), or at least Spring should log an error or warning if it finds this kind of configuration.
Affects: 4.2.5
Issue Links:
- BeanFactoryPostProcessor breaks default post-processing of @Configuration classes [SPR-8269] #12917 BeanFactoryPostProcessor breaks default post-processing of
@Configuration
classes