During upgrade from spring 3.1.1 to spring 3.2 I've come to the following question:
How can I clear "not found" value (empty array) from bean caches - singleton/nonsingleton bean names keyed by bean class - in DefaultListableBeanFacory (i.e. singletonBeanNameByType, singletonBeanNameByType)?
Scenario:
Application consists of
- several application modules, each one has it's on applicationContext with beanFacory
- shared parent application context
- modules are initialized in specified order
Now if I want to use bean from module A in module B (e.g. for autowiring) I have to publish it to shared parent application context:
parentBeanFactory.registerSingleton("moduleName" + "." + beanName, bean);
That was working in spring 3.1.1. However in spring 3.2.1 beans are cached.
During autowiring in module A:
- bean cache in DefaultListableBeanFacory is initialized with entry [Bean.class, {"beanName"}]
- bean caches in all parent bean factories are initialized with entry [Bean.class, {}]
Now If I publish the bean to the shared parent application context to be accessible from other modules:
Autowiring by @Autowired of this bean in module B fails because it has bean already cached in parent bean facory as [Bean.class, {}].Code:parentBeanFactory.registerSingleton("moduleName" + "." + beanName, bean);
How to clear this entry in parent beanFactory?
I was able to get it working with the following workaround.
Publishing beans to parent module:
Autowiring of bean in module B now works.Code:// get beanDefinition in module A ConfigurableListableBeanFactory beanFactory = (ConfigurableListableBeanFactory) applicationContext.getBeanFactory(); BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name); // use it for clearing caches in parent DefaultListableBeanFacory DefaultListableBeanFactory parentBeanFactory = (DefaultListableBeanFactory) parentContext.getBeanFactory(); parentBeanFactory.registerBeanDefinition(name, beanDefinition); parentBeanFactory.removeBeanDefinition(name); // now really publish bean to parent context String publishedName = module.getIdentifier().getId() + "." + name; parentBeanFactory.registerSingleton(publishedName, bean);
What is the correct way to do it? Or is it bug/oversight in spring?


Reply With Quote