I am trying to write a Spring BeanFactoryPostProcessor that can find any bean which defines an init-method. I am having luck finding beans that have names, but not nested nameless beans as in the target bean in following example:
<bean id="aclDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target">
<bean class="com.vidsys.dao.impl.acl.ACLDaoImpl" init-method="init">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
When I list the beans in my BeanFactoryPostProcessor I only seem to get the ones with names as in the following code:
public class BeanInitializationFinder implements BeanFactoryPostProcessor, Ordered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
//String[] beanDefs = BeanFactoryUtils.beanNamesIncludingAncestors(beanFactory);
String[] beanDefs = beanFactory.getBeanDefinitionNames();
for(String defName : beanDefs) {
BeanDefinition def = beanFactory.getBeanDefinition(defName);
if(null == def.getBeanClassName() || !(def instanceof AbstractBeanDefinition))
return;
}
AbstractBeanDefinition abd = (AbstractBeanDefinition) def;
try {
if(abd.getFactoryMethodName() == null && abd.getFactoryBeanName() == null)
Class<?> beanClass = Class.forName(abd.getBeanClassName());
if(InitializingBean.class.isAssignableFrom(beanClass) || null != abd.getInitMethodName()) {
beansWithInits.add(defName);
}
}
}
catch(Exception e) {
throw new BeanIntrospectionException("Failed to instrospect bean defs", e);
}
}
}
}
I would like to get all the bean that have an init-method, including nested beans that are nameless. Can I do that?
You can retrieve nested BeanDefinitions, but not via
beanFactory.getBeanDefinition. The only way to get to nested bean definitions is through thePropertyValuesof the parentBeanDefinition– you need to walk the graph.By way of example (and missing any null-checking):
Given that graph traversal works well with the Visitor pattern, you can subclass
org.springframework.beans.factory.config.BeanDefinitionVisitorto do this in a more concise fashion.