Spring: How to get the bean hierarchy?
Is it possible to get the开发者_运维问答 beans in which a bean was injected(Via Spring Framework)? And if yes how?
Thanks! Patrick
Here's a BeanFactoryPostProcessor
sample implementation that may help you here:
class CollaboratorsFinder implements BeanFactoryPostProcessor {
private final Object bean;
private final Set<String> collaborators = new HashSet<String>();
CollaboratorsFinder(Object bean) {
if (bean == null) {
throw new IllegalArgumentException("Must pass a non-null bean");
}
this.bean = bean;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (String beanName : BeanFactoryUtils.beanNamesIncludingAncestors(beanFactory)) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
if (beanDefinition.isAbstract()) {
continue; // assuming you're not interested in abstract beans
}
// if you know that your bean will only be injected via some setMyBean setter:
MutablePropertyValues values = beanDefinition.getPropertyValues();
PropertyValue myBeanValue = values.getPropertyValue("myBean");
if (myBeanValue == null) {
continue;
}
if (bean == myBeanValue.getValue()) {
collaborators.add(beanName);
}
// if you're not sure the same property name will be used, you need to
// iterate through the .getPropertyValues and look for the one you're
// interested in.
// you can also check the constructor arguments passed:
ConstructorArgumentValues constructorArgs = beanDefinition.getConstructorArgumentValues();
// ... check what has been passed here
}
}
public Set<String> getCollaborators() {
return collaborators;
}
}
Of course, there's a lot more to it (if you want to also catch proxies of your original bean or whatever). And, of course, the above code is completely untested.
EDIT: To make use of this, you need to declare it as a bean in your application context. As you already noticed, it requires your bean (the one you want to monitor) to be injected into it (as a constructor-arg).
As your question refers to the "bean hiearchy", I edited to look for the bean names in the entire hierarcy ...IncludingAncestors
. Also, I assumed your bean is a singleton and that it is possible to inject it into the postprocessor (although in theory the postProcessor should be initialized before other beans -- need to see if this actually works).
If you're looking for collaborating beans you could try implementing BeanFactoryAware
Just to extend David's answer - Once you implement the BeanFactoryAware - you get reference to BeanFactory which you can use to query mainly for the presence of a particualr bean in bean factory through BeanFactory.ContainsBean(String beanName).
精彩评论