当前位置: 首页 > news >正文

spring源码解析bean初始化与依赖注入四

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

前言

本文转自“天河聊技术”微信公众号

本次继续介绍spring源码解析bean初始化、依赖注入的部分

 

正文

上次介绍到这个方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean这一行

//     今早的缓存单例对象以便循环引用
      if (earlySingletonExposure) {
         Object earlySingletonReference = getSingleton(beanName, false);
         if (earlySingletonReference != null) {
            if (exposedObject == bean) {
               exposedObject = earlySingletonReference;
            }
//          初始化的bean没被包装又有依赖
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
//             获取依赖的bean
               String[] dependentBeans = getDependentBeans(beanName);
               Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
               for (String dependentBean : dependentBeans) {
                  if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                     actualDependentBeans.add(dependentBean);
                  }
               }
               if (!actualDependentBeans.isEmpty()) {
                  throw new BeanCurrentlyInCreationException(beanName,
                        "Bean with name '" + beanName + "' has been injected into other beans [" +
                        StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                        "] in its raw version as part of a circular reference, but has eventually been " +
                        "wrapped. This means that said other beans do not use the final version of the " +
                        "bean. This is often the result of over-eager type matching - consider using " +
                        "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
               }
            }
         }
      }

这一行

// Register bean as disposable.注册的bean作为可销毁的
try {
   registerDisposableBeanIfNecessary(beanName, bean, mbd);
}

进入org.springframework.beans.factory.support.AbstractBeanFactory#registerDisposableBeanIfNecessary注册可销毁的bean

*/
   protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
      AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
//    不是原型模式,可以销毁
      if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
//       如果是单例
         if (mbd.isSingleton()) {
            // Register a DisposableBean implementation that performs all destruction
            // work for the given bean: DestructionAwareBeanPostProcessors,
            // DisposableBean interface, custom destroy method.
//          注册销毁的bean,这一部分在bean定义解析的部分介绍过,这里不作介绍了
            registerDisposableBean(beanName,
                  new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
         }
         else {
            // A bean with a custom scope...
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
               throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
//          销毁后的回调方法
            scope.registerDestructionCallback(beanName,
                  new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
         }
      }
   }

返回org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean这一行

try {
//                   bean初始化
                     return createBean(beanName, mbd, args);
                  }

这里介绍完了,往下

//                    发生异常销毁单例的bean
                     destroySingleton(beanName);

进入

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingleton

public void destroySingleton(String beanName) {
      // Remove a registered singleton of the given name, if any.删除单例的bean,从本地缓存中删除
      removeSingleton(beanName);

      // Destroy the corresponding DisposableBean instance.
      DisposableBean disposableBean;
      synchronized (this.disposableBeans) {
//       从本地缓存中删除
         disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
      }
//    bean销毁的逻辑
      destroyBean(beanName, disposableBean);
   }

这一行

从factoryBean中创建的bean对象
               bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

这一行

else if (mbd.isPrototype()) {
//             bean定义为原型模式

这一行

      原型的bean创建之前维护内存中的缓存map映射信息
                  beforePrototypeCreation(beanName);
//                原型的bean创建
                  prototypeInstance = createBean(beanName, mbd, args);

进入

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])这一行

//        bean初始化之前执行beanProccessors
         Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

进入

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

@Nullable
   protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
      Object bean = null;
      if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
         // Make sure bean class is actually resolved at this point.
         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
//             调用bean初始化前处理器
               bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
               if (bean != null) {
//                bean初始化以后调用处理器
                  bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
               }
            }
         }
         mbd.beforeInstantiationResolved = (bean != null);
      }
      return bean;
   }

返回

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

这一行

//        bean创建
         Object beanInstance = doCreateBean(beanName, mbdToUse, args);

返回

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

这一行

如果类型不一致进行类型转换
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);

返回

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

这一行

for (String beanName : beanNames) {
         Object singletonInstance = getSingleton(beanName);
         if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
               AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
//                单例bean创建完成后回调
                  smartSingleton.afterSingletonsInstantiated();
                  return null;
               }, getAccessControlContext());
            }
            else {
               smartSingleton.afterSingletonsInstantiated();
            }
         }
      }

bean初始化以后触发回调

这一行

单例bean创建完成后回调
                  smartSingleton.afterSingletonsInstantiated();

返回

org.springframework.context.support.AbstractApplicationContext#refresh

这一行 bean初始化、依赖注入

finishBeanFactoryInitialization(beanFactory);

 

最后

 

本次介绍到这里,以上内容仅供参考。

转载于:https://my.oschina.net/u/3775437/blog/1813308

相关文章:

  • linux根分区满了如何处理,查找大文件方法
  • 机器中的灵魂会是量子比特么?
  • Android lrucache 实现与使用(Android内存优化)
  • 趣谈网络协议:像小说一样的网络协议入门课
  • 5.16 Stacks and Queues
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • Java 架构师眼中的 HTTP 协议
  • Java多线程干货系列—(四)volatile关键字
  • first
  • Linux Swap扩容
  • 函数的默认参数:可有可无
  • os模块注意事项
  • 腾讯云全面开放,联手千万开发者共建超级大脑
  • 【51Nod】1920 空间统计学 状压DP
  • vue-router原理剖析
  • $translatePartialLoader加载失败及解决方式
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • Leetcode 27 Remove Element
  • Promise初体验
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 码农张的Bug人生 - 见面之礼
  • 通过git安装npm私有模块
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • zabbix3.2监控linux磁盘IO
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​什么是bug?bug的源头在哪里?
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • #if #elif #endif
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • $(selector).each()和$.each()的区别
  • $jQuery 重写Alert样式方法
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (3)STL算法之搜索
  • (a /b)*c的值
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (转)一些感悟
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .net(C#)中String.Format如何使用
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • @ConfigurationProperties注解对数据的自动封装
  • @取消转义
  • []常用AT命令解释()
  • [1]-基于图搜索的路径规划基础
  • [20180129]bash显示path环境变量.txt
  • [2019.3.5]BZOJ1934 [Shoi2007]Vote 善意的投票
  • [Android Pro] android 混淆文件project.properties和proguard-project.txt
  • [BT]BUUCTF刷题第9天(3.27)
  • [C#]使用PaddleInference图片旋转四种角度检测
  • [C/C++]关于C++11中的std::move和std::forward
  • [C++从入门到精通] 14.虚函数、纯虚函数和虚析构(virtual)
  • [C++数据结构](22)哈希表与unordered_set,unordered_map实现
  • [CareerCup] 14.5 Object Reflection 对象反射
  • [cb]UIGrid+UIStretch的自适应