能否获取通过Spring Framework注入的bean中的bean?如果可以的话,如何操作?
谢谢! Patrick
这里有一个BeanFactoryPostProcessor
的示例实现,可能会对你有所帮助:
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;
}
}
当然,如果您想捕获原始bean的代理或其他内容,还有很多要做。
当然,上面的代码完全没有经过测试。
编辑: 要使用此功能,您需要在应用程序上下文中将其声明为bean。正如您已经注意到的那样,它需要将您的bean(您要监视的那个)注入其中(作为构造函数参数)。
由于您的问题涉及“bean层次结构”,因此我编辑了整个层次结构中的bean名称...IncludingAncestors
。此外,我假设您的bean是单例的,并且可以将其注入到后处理器中(尽管从理论上讲,后处理器应该在其他bean之前初始化--需要查看这是否实际起作用)。
A
注入到B
和C
中,那么在给定A
的情况下,你想要向 API 请求B
和C
吗? - skaffman