依赖查找
-
什么是双亲委派机制?
先找“老子”,再找“小子”。
双亲委派机制
HierarchicalBeanFactory
HierarchicalBeanFactory是层次性BeanFactory。
- 查看HierarchicalBeanFactory继承树
- 获取ConfigurableListableBeanFactory
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
// 设置父BeanFactory
// 调用createParentBeanFactory()方法是加载另一个BeanFactory,
beanFactory.setParentBeanFactory(createParentBeanFactory());
private static HierarchicalBeanFactory createParentBeanFactory() {
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
int i = reader.loadBeanDefinitions("classpath:/META-INF/dependency-looKup-context.xml");
return defaultListableBeanFactory;
}
- 查看当前BeanFactory是否含有Bean
//containsLocalBean(String)
public static void displayLocalBean(HierarchicalBeanFactory beanFactory, String beanName) {
System.out.printf("当前 BeanFactory[%s] 是否包含bean[name : %s] 包含了:[%s] \n", beanFactory, beanName, beanFactory.containsLocalBean(beanName));
}
这些只能查看当前的BeanFactory,并不能查看前面设置的父BeanFactory,需要改进:
- 子父全查
private static boolean containsBean(HierarchicalBeanFactory beanFactory, String beanName) {
BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();
if (parentBeanFactory instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory cast = (HierarchicalBeanFactory) parentBeanFactory;
if (containsBean(cast, beanName)) {
return true;
}
}
return beanFactory.containsLocalBean(beanName);
}
综上所述,这个双亲委派机制可以使用BeanFactoryUtils#beanNamesForTypeIncludingAncestors(包含祖先的类型的 bean 名称)获取到 “父子” BeanFactory中的Bean;
BeanFactoryUtils
public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class<?> type) {
Assert.notNull(lbf, "ListableBeanFactory must not be null");
String[] result = lbf.getBeanNamesForType(type);
if (lbf instanceof HierarchicalBeanFactory) {
HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
String[] parentResult = beanNamesForTypeIncludingAncestors(
(ListableBeanFactory) hbf.getParentBeanFactory(), type);
result = mergeNamesWithParent(result, parentResult, hbf);
}
}
return result;
}