目录

  • 一、介绍
  • 二、流程以及源码分析
    • 2.1 doCreateBean 流程图和分析
    • 2.2 doCreateBean 源码解析
  • 三、具体调用方法的详细逻辑
    • 3.1 createBeanInstance 方法解析
    • 3.2 obtainFromSupplier方法解析
    • 3.2 registerDisposableBeanIfNecessary方法解析
  • 四、总结

一、介绍

AbstractAutowireCapableBeanFactory# doCreateBean 是 AbstractBeanFactory#getBean 里面的核心,getBean 相关的整个流程可以查看
Spring源码解析之-SpringAbstractBeanFactory#getBean() 详解
主要是getBean 里面的流程细节比较多,这里单独介绍doCreateBean 的处理逻辑

二、流程以及源码分析

2.1 doCreateBean 流程图和分析


从流程图上大致可以 得出 doCreateBean 分为如下步骤:

  1. 首先 判断 是否是单例模式 ,如果是单例模式, 从 缓存 factoryBeanInstanceCache 获取,并将 缓存清楚
  2. 如果不是 单例模式,或者 缓存没有对应的value , 开始创建 实例,调用createBeanInstance 方法, createBeanInstance 方法 下面详细分析
  3. 修改 合并之后的 Bean Definition,bean 合并后的处理, Autowired 注解正是通过此方法实现诸如类型的预解析, 主要是 调用了 MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition 方法
  4. 依赖处理 ,这里有一个放入缓存,以便其他的 依赖此bean 的 , 可以提前获取到, 这里 调用 了 SmartInstantiationAwareBeanPostProcessor 的 getEarlyBeanReference 进行提前 曝光
  5. 进行填充, 调用了 populateBean方法,将各个属性值注入
  6. 初始化Bean ,这里 对 各种Aware 设置, 一些前置、后置 、initialzingBean 等相关的处理
  7. 循环检查,检查是否还有依赖的bean 没有创建
  8. 注册 disposableBeans 里面,以便在销毁bean 的时候 后置处理也生效

2.2 doCreateBean 源码解析

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper = null;// 如果定义的是单例模式,就先从缓存中清除if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}// 如果 instanceWrapper  为空,那就 创建对应的beanInstance,具体方法在下面小节分析if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {// 将 解析类型 设置 为 beanTypembd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.// 使用后置处理器 对其进行处理synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// 这里主要是 MergedBeanDefinitionPostProcessor//对@Autowire,@Value等这些注解进行处理, 相关的可以// 参考AutowiredAnnotationBeanPostProcessor  相关逻辑applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware./**是否需要提前曝光: 单例& 允许循环依赖 & 当前bean正在创建中, 检查循环依赖这里主要是调用 方法addSingletonFactory ,往缓存singletonFactories里面 放入一个 ObjectFactory当其他的bean 对该bean 有依赖时,可以提前获取到getEarlyBeanReference方法就是获取一个引用, 里面主要是调用了  SmartInstantiationAwareBeanPostProcessor,的 getEarlyBeanReference 方法,以便解决循环依赖问题, 这里 一般都是bean  本身,在 AOP时 是代理**/boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 objectFactory加入缓存// 对bean 再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor// 其中我们熟悉的AOP就是在这里将advice 动态织入,若没有直接返回beanaddSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.Object exposedObject = bean;// 下面就是初始化实例了try {// 对bean进行填充,将各个属性值注入,其中可能存在依赖于其他bean的属性,会递归初始化populateBean(beanName, mbd, instanceWrapper);//进一步初始化Bean //注入 Aware 相关的对象// 调用 后置处理器 BeanPostProcessor 里面的postProcessBeforeInitialization方法// 调用 initialzingBean,调用实现的 afterPropertiesSet()// 调用 init-mothod,调用相应的init方法                // 调用 后置处理器 BeanPostProcessor 里面的调用实现的postProcessAfterInitialization方法  exposedObject = initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}}if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);earlySingletonReference 只有在检测到有循环依赖的情况下才会不为空if (earlySingletonReference != null) {//如果exposedObject 没有在初始化方法中被改变,也就是没有被增强if (exposedObject == bean) {exposedObject = earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);// 检查依赖for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}/**因为 bean 创建后其所依赖的bean一定是已经创建,actualDependentBeans 不为空则表示 当前bean 创建后其依赖的bean 却没有全部创建,也就是说存在依赖*/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.// 注册到 disposableBeans 里面,以便在销毁bean 的时候 可以运行指定的相关业务try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}

三、具体调用方法的详细逻辑

3.1 createBeanInstance 方法解析

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {//首先确保bean 已经被解析过Class<?> beanClass = resolveBeanClass(mbd, beanName);// 如果beanClass 不是public 类型,那么就 抛出异常,提示   non-public access not allowedif (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());}// 如果存在,就返回一个  callback回调函数,在 obtainFromSupplier 方法里面//调用对应的具体方法 ,并转换成 BeanWrapper 类型Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {// 这里转换成 BeanWrapper  类型return obtainFromSupplier(instanceSupplier, beanName);}// 如果存在对应的工厂方法,那么就使用工厂方法进行初始化if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...boolean resolved = false;boolean autowireNecessary = false;if (args == null) {synchronized (mbd.constructorArgumentLock) {//一个类有多个构造函数,每个构造商数都有不同的参数,所以调用前前需要先根据参数锁定构 //边的数或对应的工厂方法 if (mbd.resolvedConstructorOrFactoryMethod != null) {// 设置 已经解析resolved = true;autowireNecessary = mbd.constructorArgumentsResolved;}}}//如果已经解析过则使用解析好的构造函数方法,不用再次锁定 if (resolved) {// 构造函数参数都已经解析完if (autowireNecessary) {// 使用构造函数自动注入return autowireConstructor(beanName, mbd, null, null);}else {//使用其默认构造函数实例化给定的beanreturn instantiateBean(beanName, mbd);}}// Candidate constructors for autowiring?// 如果上面没有解析好对应的构造函数, 这里看看有没有指定构造函数/**具体里面其实 是 SmartInstantiationAwareBeanPostProcessor , 这个类 继承了InstantiationAwareBeanPostProcessor, 调用里面的determineCandidateConstructors 方法 来确认有没有指定的构造函数*/Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {// 构造函数自动注入return autowireConstructor(beanName, mbd, ctors, args);}// 获取确定用于默认构造的首选构造函数(如果有)。 如有必要,构造函数参数将自动装配。ctors = mbd.getPreferredConstructors();if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);}// 默认使用无参构造函数return instantiateBean(beanName, mbd);}

3.2 obtainFromSupplier方法解析

 protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {Object instance;// 获取原先的 上下文的outerBeanString outerBean = this.currentlyCreatedBean.get();// 替换为 当前的beanNamethis.currentlyCreatedBean.set(beanName);try {// 调用具体的方法进行instance 创建instance = instanceSupplier.get();}finally {if (outerBean != null) {// 替换为原先的值this.currentlyCreatedBean.set(outerBean);}else {// 为空那就移除this.currentlyCreatedBean.remove();}}if (instance == null) {instance = new NullBean();}// 进行BeanWrapper 转换BeanWrapper bw = new BeanWrapperImpl(instance);// 对 bw 进行初始化,并对PropertyEditorRegistry 进行初始化initBeanWrapper(bw);return bw;}// 用 被BeanFactory注册过的 自定义编辑器 对PropertyEditorRegistry 进行初始化
protected void registerCustomEditors(PropertyEditorRegistry registry) {// 判断能否转成 实现类 PropertyEditorRegistrySupportPropertyEditorRegistrySupport registrySupport =(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);// 设置 configValueEditorsActive 属性为 true ,用于激活 配置值的编辑器if (registrySupport != null) {registrySupport.useConfigValueEditors();}// 如果存在 自定义 PropertyEditorRegistrar if (!this.propertyEditorRegistrars.isEmpty()) {// 遍历注册一遍for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {try {registrar.registerCustomEditors(registry);}catch (BeanCreationException ex) {Throwable rootCause = ex.getMostSpecificCause();// 如果抛出的是 BeanCurrentlyInCreationException ,正在创建的异常,// 先将 ex 转换为 BeanCreationException,再获取对应的bceBeanName// if (rootCause instanceof BeanCurrentlyInCreationException) {BeanCreationException bce = (BeanCreationException) rootCause;String bceBeanName = bce.getBeanName();if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) {if (logger.isDebugEnabled()) {logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +"] failed because it tried to obtain currently created bean '" +ex.getBeanName() + "': " + ex.getMessage());}// 加入 suppressedExceptions 列表,并跳过onSuppressedException(ex);continue;}}throw ex;}}}// 如果存在自定义 PropertyEditorsif (!this.customEditors.isEmpty()) {// 遍历进行注册 CustomEditorthis.customEditors.forEach((requiredType, editorClass) ->registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));}}

3.2 registerDisposableBeanIfNecessary方法解析

 protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);/** 不是原型模式,并且默认实现检查DisposableBean接口以及指定的destroy方法和已注册的DestructionAwareBeanPostProcessors。后续在销毁的时候 ,就可以运行后置处理相关的业务**/if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {if (mbd.isSingleton()) {/**注册一个DisposableBean实现,该实现执行给定bean的所有销毁工作:    DestructionAwareBeanPostProcessors,DisposableBean接口,自定义destroy方法。主要就是 放入到 disposableBeans 里面**/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));}}}

四、总结

先大致 对源码进行解读,后面再详细分析各个点.

支付宝 微信
如果有帮助记得打赏哦 特别需要您的打赏哦

Spring源码解析之-doCreateBean() 详解相关推荐

  1. ROS Navigation之amcl源码解析(完全详解)

    转载于:https://haoqchen.site/2018/05/06/amcl-code/ 0. 写在最前面 本文持续更新地址:https://haoqchen.site/2018/05/06/a ...

  2. log4j 源码解析_Log4j配置详解

    log4j.rootLogger=INFO,consoleAppender,logfile,errorlogfile log4j.addivity.org.apache=true #文件输出:Roll ...

  3. Redis源码解析:数据结构详解-skiplist

    跳表是个什么数据结构? 本文的很多内容参考自如下文章<Redis 为什么用跳表而不用平衡树?>,为了加深理解,所以用自己的话复述一遍. 如图所示,redis中的zset在元素少的时候用zi ...

  4. Spring源码解析 -- SpringWeb请求映射Map初始化

    简介 在上篇文章中,大致解析了Spring如何将请求路径与处理方法进行映射,但映射相关的初始化对于我们来说还是一团迷雾 本篇文章就来探索下,请求路径和处理方法的映射,是如何进行初始化的 概览 基于上篇 ...

  5. Spring源码解析【完整版】--【bilibili地址:https://www.bilibili.com/video/BV1oW41167AV】

    [本文为bilibili视频雷丰阳的Spring源码解析的完整版总结文章,其中文章前面大部分为他人博文的搬运,后面补充了其未总结的部分] 一.Java的注解 1. 注解的概念 注释:用文字描述程序,给 ...

  6. React 源码系列 | React Context 详解

    目前来看 Context 是一个非常强大但是很多时候不会直接使用的 api.大多数项目不会直接使用 createContext 然后向下面传递数据,而是采用第三方库(react-redux). 想想项 ...

  7. 人人都能看懂的Spring源码解析,Spring如何解决循环依赖

    人人都能看懂的Spring源码解析,Spring如何解决循环依赖 原理解析 什么是循环依赖 循环依赖会有什么问题? 如何解决循环依赖 问题的根本原因 如何解决 为什么需要三级缓存? Spring的三级 ...

  8. Spring 源码解析 - Bean创建过程 以及 解决循环依赖

    一.Spring Bean创建过程以及循环依赖 上篇文章对 Spring Bean资源的加载注册过程进行了源码梳理和解析,我们可以得到结论,资源文件中的 bean 定义信息,被组装成了 BeanDef ...

  9. Spring源码解析 - AbstractBeanFactory 实现接口与父类分析

    2019独角兽企业重金招聘Python工程师标准>>> 我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegi ...

  10. Xposed源码剖析——app_process作用详解

    Xposed源码剖析--app_process作用详解 首先吐槽一下CSDN的改版吧,发表这篇文章之前其实我已经将此篇文章写过了两三次了.就是发表不成功.而且CSDN将我的文章草稿也一带>删除掉 ...

最新文章

  1. 连接以太网测试网Ropsten,本地账号和remix余额显示为0不同步的问题,Remix连接
  2. DVWA系列之21 存储型XSS分析与利用
  3. 2016/8/18 Linux常用命令 :目录、文件处理命令
  4. Linux内核深入理解中断和异常(8):串口驱动程序
  5. 关于钥匙串中所有证书签名无效的问题解决纪录
  6. linux 运行python 看不到异常信息_Linux异常解决:/usr/bin/env python\r no such file or directory...
  7. Jupyter Notebook中未显示Conda环境
  8. 学计算机高中选那三科,高中选哪三科最吃香
  9. spring史上最全笔记
  10. 舅妈的计算机课第2部,名著课 | 题:《简·爱》(二)
  11. Opencv inRang() 和HSV色彩空间表
  12. 【Web技术】929- 前端海报生成的不同方案和优劣
  13. 2008威客模式网站有哪些创新
  14. 二叉树的遍历(二叉树与递归算法)
  15. QT问题解决:the code model could not parse an included file,
  16. openGL包含gl.h/glu.h/glaux.h/glut.h/报错
  17. 《写给大家看的设计书》(第四版)
  18. Spring Data JPA OneToMany级联,多方删除修改新增详解(好文章!!申精!!)
  19. 软件加密保护中加密狗软加密跟硬加密的安全强度
  20. 【DETR源码解析】三、Transformer模块

热门文章

  1. 工资管理系统数据库设计
  2. 学习人工智能导论(1)
  3. qt.qpa.plugin: Could not load the Qt platform plugin “xcb“ in
  4. linux无线网卡信道,linux如何列出网卡支持的wifi信道?
  5. 【Java面试题】线程的生命周期包括哪几个阶段?
  6. 希腊字母表 ← LaTeX
  7. Chrome插件开发教程
  8. 官方解决方案:WPS for Mac 云字体删除的问题,Mac版WPS已下载云字体无法删除的问题
  9. 怎么做直播APP软件?
  10. Latex beamer制作ppt