I've implemented a system which requires runtime register/unregistering of a bean definition. But sometimes we need to register a few inner bean definitions as well.
Currently the code is something like this:
It works but it's inheritly unsafe; BeanDefintionRegistry implementation seems thread safe yes, but a number of race conditions could be happening here. Is there a way to do all the above registration atomically right out of the box? I guess I could extend the DefaultSingletonBeanRegistry and do all this while holding a lock but I was just wondering if it was possible now.Code:List<String> registered = new LinkedList<String>(); try { GenericBeanDefionition beanDef = new GenericBeanDefinition(); myCustomWrapper.populate(beanDef); for (BeanDefinitionHolder holder : myCustomWrapper.getInnerBeans()) { beanDefRegistry.register(holder.getBeanName(), holder.getBeanDefinition()); registered.add(holder.getBeanName()); } registry.registerBeanDefinition("unique name", beanDef); registered.add("unique name"); if (registry instanceof DefaultSingletonBeanRegistry) { // register contained beans } } catch (BeanDefinitionStoreException e) { for (String successfullyRegistered : registered) { try { registry.removeBeanDefinition(s); } catch (NoSuchBeanDefinitionException ignore) {} } throw e; } try { return applicationContext.getBean("unique name", ExpectedBeanClass.class); } catch (BeansException e) { // rollback everything throw e; }
There are already suitable interfaces and implementations for this, appararently only used for tooling: ComponentDefintinion, which could do the job if accepted through BDRegistry interface.
All above is Spring 3.0 while most of it was already supported in 2.5.
Yes, OSGi might make some sense here as well but if we disregard it for now? Same goes for creating a new child application context per my registered component.


Reply With Quote
