BeanDefinition 的合并
- 1.BeanDefinition 有父子关系,有个属性叫
parentName,通过parentName可以设置BeanDefinition的父子关系 - 2.为什么要设置BeanDefinition的父子关系,因为子类可以继承父类的属性,抽出共性,跟java的继承有点像
- 3.BeanDefinition 的合并过程就是将父子关系的 BeanDefinition 属性合并起来,如果有相同的就使用子类的属性值 例子:
AnnotationConfigApplicationContext applicationContext
= new AnnotationConfigApplicationContext(springConfiguration.class);
//父 RootBeanDefinition
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setScope(AbstractBeanDefinition.SCOPE_DEFAULT);
rootBeanDefinition.getPropertyValues().add("name","xiaoming");
applicationContext.registerBeanDefinition("parent",rootBeanDefinition);
//子 ChildBeanDefinition ,会继承使用父类已有的属性值,但是如果属性值冲突,不一样
//那么合并过程中就会使用子类的
ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition("parent");
childBeanDefinition.setBeanClass(A.class);
childBeanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
什么时候做合并
在初始化bean工厂的过程中调用: PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors->DefaultListableBeanFactory.getBeanNamesForType
- DefaultListableBeanFactory.getBeanNamesForType
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
//.......
return doGetBeanNamesForType
//......
}
- DefaultListableBeanFactory#doGetBeanNamesForType
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<>();
// 遍历所有的 beanDefinitionNames
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name
// is not defined as alias for some other bean.
if (!isAlias(beanName)) {
try {
//获取合并的bd
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//.....
}
- AbstractBeanFactory#getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// 先尝试从缓存获取bd(就是一个map)
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
//合并bd
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
- AbstractBeanFactory#getMergedBeanDefinition
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// 先从缓存拿合并的bd
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
//合并的bd为空就进行bd合并
if (mbd == null) {
//如果父类为空,就不进行bd合并
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
// 进行bd合并
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
//父类的bd可能也需要合并,所以调用 getMergedBeanDefinition
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
}
}
//进行bd合并,子类覆盖父类的,如果子类没有,就用父类的属性
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
}
return mbd;
}
}