Thanks to some serious spring debugging, we found that the DependantBean parameter to BeanFactoryPostProcessorConfiguration caused the impatient initialization of the other (unrelated) beans. But since spring was at the BeanFactoryPostProcessor stage, BeanPostProcessors were not ready.
Reading the javadoc for BeanFactoryPostProcessor (thanks @Pavel for pointing this out) exactly explains the problem:
BeanFactoryPostProcessor can interact and define bean definitions, but never bean instances. This can lead to premature bean creation, container malfunction, and unintended side effects. If interaction with a bean instance is required, consider implementing {@link BeanPostProcessor}.
Decision:
Slightly modified applicationContext.xml :
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.stackoverflow.springbug.beanfactorydependencyissue.other" /> </beans>
New bootstrapContext.xml : (note that only packages are different)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.stackoverflow.springbug.beanfactorydependencyissue.bootstrap" /> </beans>
New Contexts.java : (Note that bootstrap is the parent context for the regular applicationContext)
package com.stackoverflow.springbug.beanfactorydependencyissue; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; public final class Contexts { private static Supplier<ApplicationContext> bootstrap = Suppliers.memoize(new Supplier<ApplicationContext>(){ public ApplicationContext get() { return new ClassPathXmlApplicationContext("/bootstrapContext.xml"); } }); public static ApplicationContext bootstrap() { return bootstrap.get(); } private static Supplier<ApplicationContext> applicationContext = Suppliers.memoize(new Supplier<ApplicationContext>(){ public ApplicationContext get() { return new ClassPathXmlApplicationContext(new String[]{"/applicationContext.xml"}, bootstrap()); } }); public static ApplicationContext applicationContext() { return applicationContext.get(); } }
BeanFactoryPostProcessorConfiguration without DependantBean as a parameter:
package com.stackoverflow.springbug.beanfactorydependencyissue.other; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.stackoverflow.springbug.beanfactorydependencyissue.Contexts; import com.stackoverflow.springbug.beanfactorydependencyissue.bootstrap.DependantBean; @Configuration public class BeanFactoryPostProcessorConfiguration { @Bean public static BeanFactoryPostProcessor beanFactoryPostProcessor() { final DependantBean dependantBean = Contexts.bootstrap().getBean(DependantBean.class); System.out.println(dependantBean.getDependencyBean()); return new BeanFactoryPostProcessor(){ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { } }; } }
The last thing to do is move the DependantBean and DependencyBean to the bootstrap package. The goal was reached to read @Value properties from the database. Reusing old beans definitions and not duplicating beans.
jontejj
source share