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<>();// 遍历所有的 beanDefinitionNamesfor (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 {//获取合并的bdRootBeanDefinition 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;}//合并bdreturn getMergedBeanDefinition(beanName, getBeanDefinition(beanName));}
复制代码
AbstractBeanFactory#getMergedBeanDefinition
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {synchronized (this.mergedBeanDefinitions) {RootBeanDefinition mbd = null;// 先从缓存拿合并的bdif (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可能也需要合并,所以调用 getMergedBeanDefinitionpbd = 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;} }复制代码