BeanDefinition 合并

举报
JavaEdge 发表于 2021/06/03 23:23:01 2021/06/03
【摘要】   BeanDefinition 的合并 1.BeanDefinition 有父子关系,有个属性叫parentName,通过parentName可以设置BeanDefinition的父子关系2.为什么要设置BeanDefinition的父子关系,因为子类可以继承父类的属性,抽出共性,跟java的继承有点像3.BeanDefinition 的合并过程就是将父子关系...

 

BeanDefinition 的合并

  • 1.BeanDefinition 有父子关系,有个属性叫parentName,通过parentName可以设置BeanDefinition的父子关系
  • 2.为什么要设置BeanDefinition的父子关系,因为子类可以继承父类的属性,抽出共性,跟java的继承有点像
  • 3.BeanDefinition 的合并过程就是将父子关系的 BeanDefinition 属性合并起来,如果有相同的就使用子类的属性值 例子:
    
        
    1. AnnotationConfigApplicationContext applicationContext
    2. = new AnnotationConfigApplicationContext(springConfiguration.class);
    3. //父 RootBeanDefinition
    4. RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
    5. rootBeanDefinition.setScope(AbstractBeanDefinition.SCOPE_DEFAULT);
    6. rootBeanDefinition.getPropertyValues().add("name","xiaoming");
    7. applicationContext.registerBeanDefinition("parent",rootBeanDefinition);
    8. //子 ChildBeanDefinition ,会继承使用父类已有的属性值,但是如果属性值冲突,不一样
    9. //那么合并过程中就会使用子类的
    10. ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition("parent");
    11. childBeanDefinition.setBeanClass(A.class);
    12. childBeanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
    13. 复制代码

    什么时候做合并

    在初始化bean工厂的过程中调用: PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors->DefaultListableBeanFactory.getBeanNamesForType
  • DefaultListableBeanFactory.getBeanNamesForType

  
  1. public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
  2. //.......
  3. return doGetBeanNamesForType
  4. //......
  5. }
  6. 复制代码
  • DefaultListableBeanFactory#doGetBeanNamesForType

  
  1. private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
  2. List<String> result = new ArrayList<>();
  3. // 遍历所有的 beanDefinitionNames
  4. for (String beanName : this.beanDefinitionNames) {
  5. // Only consider bean as eligible if the bean name
  6. // is not defined as alias for some other bean.
  7. if (!isAlias(beanName)) {
  8. try {
  9. //获取合并的bd
  10. RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
  11. //.....
  12. }
  13. 复制代码
  • AbstractBeanFactory#getMergedLocalBeanDefinition

  
  1. protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
  2. // 先尝试从缓存获取bd(就是一个map)
  3. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
  4. if (mbd != null) {
  5. return mbd;
  6. }
  7. //合并bd
  8. return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
  9. }
  10. 复制代码
  • AbstractBeanFactory#getMergedBeanDefinition

    
        
    1. protected RootBeanDefinition getMergedBeanDefinition(
    2. String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
    3. throws BeanDefinitionStoreException {
    4. synchronized (this.mergedBeanDefinitions) {
    5. RootBeanDefinition mbd = null;
    6. // 先从缓存拿合并的bd
    7. if (containingBd == null) {
    8. mbd = this.mergedBeanDefinitions.get(beanName);
    9. }
    10. //合并的bd为空就进行bd合并
    11. if (mbd == null) {
    12. //如果父类为空,就不进行bd合并
    13. if (bd.getParentName() == null) {
    14. // Use copy of given root bean definition.
    15. if (bd instanceof RootBeanDefinition) {
    16. mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
    17. }
    18. else {
    19. mbd = new RootBeanDefinition(bd);
    20. }
    21. }
    22. else {
    23. // 进行bd合并
    24. BeanDefinition pbd;
    25. try {
    26. String parentBeanName = transformedBeanName(bd.getParentName());
    27. if (!beanName.equals(parentBeanName)) {
    28. //父类的bd可能也需要合并,所以调用 getMergedBeanDefinition
    29. pbd = getMergedBeanDefinition(parentBeanName);
    30. }
    31. else {
    32. BeanFactory parent = getParentBeanFactory();
    33. if (parent instanceof ConfigurableBeanFactory) {
    34. pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
    35. }
    36. }
    37. }
    38. //进行bd合并,子类覆盖父类的,如果子类没有,就用父类的属性
    39. mbd = new RootBeanDefinition(pbd);
    40. mbd.overrideFrom(bd);
    41. }
    42. // Set default singleton scope, if not configured before.
    43. if (!StringUtils.hasLength(mbd.getScope())) {
    44. mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
    45. }
    46. }
    47. return mbd;
    48. }
    49. }
    50. 复制代码

 

文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。

原文链接:javaedge.blog.csdn.net/article/details/108177864

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。