spring源码版本5.0.5

概述

该方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。

分析

跟踪到AbstractApplicationContext.refresh()方法,找到代码finishBeanFactoryInitialization(beanFactory)查看实现。

  1. protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  2. // Initialize conversion service for this context.
  3. // 1.初始化此上下文的转换服务
  4. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
  5. beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
  6. beanFactory.setConversionService(
  7. beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
  8. }
  9.  
  10. // Register a default embedded value resolver if no bean post-processor
  11. // (such as a PropertyPlaceholderConfigurer bean) registered any before:
  12. // at this point, primarily for resolution in annotation attribute values.
  13. // 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析
  14. if (!beanFactory.hasEmbeddedValueResolver()) {
  15. beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
  16. }
  17.  
  18. // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
  19. // 3.初始化LoadTimeWeaverAware Bean实例对象
  20. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
  21. for (String weaverAwareName : weaverAwareNames) {
  22. getBean(weaverAwareName);
  23. }
  24.  
  25. // Stop using the temporary ClassLoader for type matching.
  26. beanFactory.setTempClassLoader(null);
  27.  
  28. // Allow for caching all bean definition metadata, not expecting further changes.
  29. // 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
  30. beanFactory.freezeConfiguration();
  31.  
  32. // Instantiate all remaining (non-lazy-init) singletons.
  33. // 5.实例化所有剩余(非懒加载)单例对象
  34. beanFactory.preInstantiateSingletons();
  35. }

继续跟踪到DefaultListableBeanFactory#preInstantiateSingletons

  1. public void preInstantiateSingletons() throws BeansException {
  2. if (this.logger.isDebugEnabled()) {
  3. this.logger.debug("Pre-instantiating singletons in " + this);
  4. }
  5.  
  6. // Iterate over a copy to allow for init methods which in turn register new bean definitions.
  7. // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
  8. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
  9.  
  10. // Trigger initialization of all non-lazy singleton beans...
  11. //遍历beanNames,触发所有非懒加载单例bean的初始化
  12. for (String beanName : beanNames) {
  13. RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
  14. //Bean实例:不是抽象类 && 是单例 && 不是懒加载
  15. if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
  16. //判断beanName对应的bean是否为FactoryBean
  17. if (isFactoryBean(beanName)) {
  18. //通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例
  19. Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
  20. if (bean instanceof FactoryBean) {
  21. final FactoryBean<?> factory = (FactoryBean<?>) bean;
  22. //判断这个FactoryBean是否希望急切的初始化
  23. boolean isEagerInit;
  24. if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
  25. isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
  26. ((SmartFactoryBean<?>) factory)::isEagerInit,
  27. getAccessControlContext());
  28. }
  29. else {
  30. isEagerInit = (factory instanceof SmartFactoryBean &&
  31. ((SmartFactoryBean<?>) factory).isEagerInit());
  32. }
  33. if (isEagerInit) {
  34. getBean(beanName);
  35. }
  36. }
  37. }
  38. else {
  39. //如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例
  40. getBean(beanName);
  41. }
  42. }
  43. }
  44.  
  45. ......
  46. }

要理解FactoryBean和Bean的区别

一般情况下,Spring 通过反射机制利用 bean 的  class 属性指定实现类来实例化 bean。而 FactoryBean 是一种特殊的 bean,它是个工厂 bean,可以自己创建 bean 实例,如果一个类实现了 FactoryBean 接口,则该类可以自己定义创建实例对象的方法,只需要实现它的 getObject() 方法。

注:很多中间件都利用 FactoryBean 来进行扩展。

引入了几个重要的缓存:

  • mergedBeanDefinitions 缓存:beanName -> 合并的 bean 定义。
  • beanDefinitionMap 缓存:beanName -> BeanDefinition。
  • singletonObjects 缓存:beanName -> 单例 bean 对象。
  • earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
  • singletonFactories 缓存:beanName -> ObjectFactory。
  • singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。

继承跟踪到AbstractBeanFactory#doGetBean创建bean

  1. protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
  2. @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
  3.  
  4. //解析beanName,主要是解析别名、去掉FactoryBean的前缀“&”
  5. final String beanName = transformedBeanName(name);
  6. Object bean;
  7.  
  8. // Eagerly check singleton cache for manually registered singletons.
  9. //尝试从缓存中获取beanName对应的实例,通过缓存解决循环依赖问题
  10. Object sharedInstance = getSingleton(beanName);
  11. if (sharedInstance != null && args == null) {
  12. if (logger.isDebugEnabled()) {
  13. if (isSingletonCurrentlyInCreation(beanName)) {
  14. logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
  15. "' that is not fully initialized yet - a consequence of a circular reference");
  16. }
  17. else {
  18. logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
  19. }
  20. }
  21. //返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)
  22. bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  23. }
  24.  
  25. else {
  26. // Fail if we're already creating this bean instance:
  27. // We're assumably within a circular reference.
  28. // scope为prototype非单例的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常。
  29. // 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖
  30. if (isPrototypeCurrentlyInCreation(beanName)) {
  31. throw new BeanCurrentlyInCreationException(beanName);
  32. }
  33.  
  34. // Check if bean definition exists in this factory.
  35. BeanFactory parentBeanFactory = getParentBeanFactory();
  36. //如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例
  37. if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
  38. // Not found -> check parent.
  39. String nameToLookup = originalBeanName(name);
  40. if (parentBeanFactory instanceof AbstractBeanFactory) {
  41. return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
  42. nameToLookup, requiredType, args, typeCheckOnly);
  43. }
  44. else if (args != null) {
  45. // Delegation to parent with explicit args.
  46. return (T) parentBeanFactory.getBean(nameToLookup, args);
  47. }
  48. else {
  49. // No args -> delegate to standard getBean method.
  50. return parentBeanFactory.getBean(nameToLookup, requiredType);
  51. }
  52. }
  53.  
  54. if (!typeCheckOnly) {
  55. //如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
  56. markBeanAsCreated(beanName);
  57. }
  58.  
  59. try {
  60. final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
  61. checkMergedBeanDefinition(mbd, beanName, args);
  62.  
  63. // Guarantee initialization of beans that the current bean depends on.
  64. //拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean,如使用@DependsOn
  65. String[] dependsOn = mbd.getDependsOn();
  66. if (dependsOn != null) {
  67. for (String dep : dependsOn) {
  68. if (isDependent(beanName, dep)) {
  69. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  70. "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
  71. }
  72. registerDependentBean(dep, beanName);
  73. try {
  74. getBean(dep);
  75. }
  76. catch (NoSuchBeanDefinitionException ex) {
  77. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  78. "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
  79. }
  80. }
  81. }
  82.  
  83. // Create bean instance.
  84. if (mbd.isSingleton()) {
  85. //scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法,在里面创建bean
  86. sharedInstance = getSingleton(beanName, () -> {
  87. try {
  88. return createBean(beanName, mbd, args);
  89. }
  90. catch (BeansException ex) {
  91. // Explicitly remove instance from singleton cache: It might have been put there
  92. // eagerly by the creation process, to allow for circular reference resolution.
  93. // Also remove any beans that received a temporary reference to the bean.
  94. destroySingleton(beanName);
  95. throw ex;
  96. }
  97. });
  98. //返回beanName对应的实例对象
  99. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  100. }
  101.  
  102. //其它非单例的情况,暂不分析
  103. ......
  104. }
  105. catch (BeansException ex) {
  106. cleanupAfterBeanCreationFailure(beanName);
  107. throw ex;
  108. }
  109. }
  110.  
  111. ......
  112. return (T) bean;
  113. }

查看DefaultSingletonBeanRegistry#getSingleton

  1. public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  2. Assert.notNull(beanName, "Bean name must not be null");
  3. synchronized (this.singletonObjects) {
  4. //首先检查beanName对应的bean实例是否在缓存中存在,如果已经存在,则直接返回
  5. Object singletonObject = this.singletonObjects.get(beanName);
  6. if (singletonObject == null) {
  7. if (this.singletonsCurrentlyInDestruction) {
  8. throw new BeanCreationNotAllowedException(beanName,
  9. "Singleton bean creation not allowed while singletons of this factory are in destruction " +
  10. "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
  11. }
  12. if (logger.isDebugEnabled()) {
  13. logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
  14. }
  15. //创建单例前的操作,把bean放入正准备创建的一个Set中singletonsCurrentlyInCreation,如果重复会报异常
  16. //如果存在构造器循环依赖的时候(A(B b),B(C c),C(A a)),会在这点报出异常
  17. beforeSingletonCreation(beanName);
  18. boolean newSingleton = false;
  19. boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
  20. if (recordSuppressedExceptions) {
  21. this.suppressedExceptions = new LinkedHashSet<>();
  22. }
  23. try {
  24. //执行singletonFactory的getObject方法获取bean实例,就是执行传入方法createBean
  25. singletonObject = singletonFactory.getObject();
  26. newSingleton = true;
  27. }
  28.  
  29. ......
  30.  
  31. finally {
  32. if (recordSuppressedExceptions) {
  33. this.suppressedExceptions = null;
  34. }
  35. //创建单例后的操作,在singletonsCurrentlyInCreation中移除
  36. afterSingletonCreation(beanName);
  37. }
  38. if (newSingleton) {
  39. addSingleton(beanName, singletonObject);
  40. }
  41. }
  42. return singletonObject;
  43. }
  44. }

继承跟踪AbstractAutowireCapableBeanFactory#createBean

  1. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  2. throws BeanCreationException {
  3.  
  4. ......
  5.  
  6. try {
  7. //验证及准备覆盖的方法(对override属性进行标记及验证)
  8. mbdToUse.prepareMethodOverrides();
  9. }
  10. catch (BeanDefinitionValidationException ex) {
  11. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
  12. beanName, "Validation of method overrides failed", ex);
  13. }
  14.  
  15. try {
  16. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  17. //实例化前的处理,如果有实现InstantiationAwareBeanPostProcessor的BeanPostProcessor可以直接返回真正的bean实例
  18. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  19. if (bean != null) {
  20. return bean;
  21. }
  22. }
  23. catch (Throwable ex) {
  24. throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
  25. "BeanPostProcessor before instantiation of bean failed", ex);
  26. }
  27.  
  28. try {
  29. //创建Bean实例(一般真正创建Bean的方法)
  30. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  31. if (logger.isDebugEnabled()) {
  32. logger.debug("Finished creating instance of bean '" + beanName + "'");
  33. }
  34. return beanInstance;
  35. }
  36. ......
  37. }

实例化前的处理,给 InstantiationAwareBeanPostProcessor 一个机会返回代理对象来替代真正的 bean 实例,从而跳过 Spring 默认的实例化过程,达到“短路”效果。会执行 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法,该方法可以返回 bean 实例的代理,从而跳过 Spring 默认的实例化过程。

查看AbstractAutowireCapableBeanFactory#doCreateBean,这个方法非常重要

  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
  2. throws BeanCreationException {
  3.  
  4. // Instantiate the bean.
  5. BeanWrapper instanceWrapper = null;
  6. if (mbd.isSingleton()) {
  7. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  8. }
  9. if (instanceWrapper == null) {
  10. //根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrappe
  11. instanceWrapper = createBeanInstance(beanName, mbd, args);
  12. }
  13. // todo !!!!!!!!这里获取出来的对象是原生对象!!!!!
  14. final Object bean = instanceWrapper.getWrappedInstance();
  15. Class<?> beanType = instanceWrapper.getWrappedClass();
  16. if (beanType != NullBean.class) {
  17. mbd.resolvedTargetType = beanType;
  18. }
  19.  
  20. ......
  21.  
  22. // Eagerly cache singletons to be able to resolve circular references
  23. // even when triggered by lifecycle interfaces like BeanFactoryAware.
  24. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  25. isSingletonCurrentlyInCreation(beanName));
  26. if (earlySingletonExposure) {
  27. if (logger.isDebugEnabled()) {
  28. logger.debug("Eagerly caching bean '" + beanName +
  29. "' to allow for resolving potential circular references");
  30. }
  31. //注意这点,曝光beanName的ObjectFactory,用于解决循环引用。 在开始通过doGetBean取值的时候调用了getSingleton就调用到这个工厂来了
  32. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  33. }
  34.  
  35. // Initialize the bean instance.
  36. Object exposedObject = bean;
  37. try {
  38. //todo 对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例
  39. //设置属性,非常重要,比如使用@Autowired注入的值等
  40. populateBean(beanName, mbd, instanceWrapper);
  41.  
  42. // todo 经过AOP处理,原生对象转换成了代理对象,跟进去
  43. //执行后置处理器,aop就是在这里完成的处理
  44. exposedObject = initializeBean(beanName, exposedObject, mbd);
  45. }
  46.  
  47. ......
  48.  
  49. return exposedObject;
  50. }

实例化对象createBeanInstance,就是选出一个策略来实例化一个对象, 那有什么策略呢? 这就看程序员是怎么配置的了, 程序员可以配置工厂方法,指定构造方法,或者是程序员没有做出任何干涉,让Spring按自己的方式去实例化

参考:

https://www.cnblogs.com/ZhuChangwu/p/11755973.html

https://blog.csdn.net/v123411739/category_8589693.html

spring的finishBeanFactoryInitialization方法分析的更多相关文章

  1. Spring BeanFacoty doCreateBean方法分析

    上一篇,我们分析到了doCreateBean,现在继续: 先看看时序图 protected Object doCreateBean(final String beanName, final RootB ...

  2. spring容器的refresh方法分析

    spring源码版本5.0.5 Spring容器创建之后,会调用它的refresh方法刷新Spring应用的上下文. 首先整体查看AbstractApplicationContext#refresh源 ...

  3. Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean

    Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean 七千字长文深刻解读,Spirng中是如何初始化单例bean的,和面试中最常问的Sprin ...

  4. Spring Ioc源码分析系列--容器实例化Bean的四种方法

    Spring Ioc源码分析系列--实例化Bean的几种方法 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到bean真正通过那些方式实例化出来的时候,并没有继续分 ...

  5. spring IOC源码分析(ApplicationContext)

    在上一篇文章中,我们以BeanFactory这条主线进行IOC的源码解析的,这里,将以ApplicationContext这条线进行分析.先看使用方法: @Test public void testA ...

  6. Spring IOC 源码分析

    Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 Spring 呢?阅读本文 ...

  7. Spring Boot源码分析-启动过程

    Spring Boot作为目前最流行的Java开发框架,秉承"约定优于配置"原则,大大简化了Spring MVC繁琐的XML文件配置,基本实现零配置启动项目. 本文基于Spring ...

  8. SpringBoot框架——从SpringBoot看IoC容器初始化流程之方法分析

    目录 一.概观Spring Boot 二.Spring Boot应用初始化 2.1 初始化入口 2.2 SpringApplication的run方法 2.3 方法分析 三.容器创建与初始化 3.1 ...

  9. 5.2 Spring5源码--Spring AOP源码分析二

    目标: 1. 什么是AOP, 什么是AspectJ 2. 什么是Spring AOP 3. Spring AOP注解版实现原理 4. Spring AOP切面原理解析 一. 认识AOP及其使用 详见博 ...

随机推荐

  1. Hanlp-地名识别调试方法详解

    HanLP收词特别是实体比较多,因此特别容易造成误识别.下边举几个地名误识别的例子,需要指出的是,后边的机构名识别也以地名识别为基础,因此,如果地名识别不准确,也会导致机构名识别不准确. 类型1 数字 ...

  2. 把Javascript 对象转换为键值对连接符字符串的方法总结

    307down votefavorite 93 Do you know a fast and simple way to encode a Javascript Object into a strin ...

  3. Linux 下安装 redis5.0

    1.redis 安装 wget http://download.redis.io/rele... tar -zxvf redis-5.0.5.tar.gz cd redis-5.0.5.tar.gz ...

  4. 如何使用RedisTemplate访问Redis数据结构之字符串操作

    Redis 数据结构简介 Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有序集 ...

  5. (十一)springMvc 异常处理

    文章目录 思路 自定义异常处理类 全局异常处理器 配置全局异常处理器 思路 在 springMvc 中,异常一层一层的往上抛,最后抛给 前端控制器,前端控制器内部会去找 全局异常处理器(一个系统只会有 ...

  6. Kindergarten(网络流解法)

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=2458 问你二分图的最大团是多大. #define IOS ios_base::sync_with_stdi ...

  7. 【深度森林第三弹】周志华等提出梯度提升决策树再胜DNN

    [深度森林第三弹]周志华等提出梯度提升决策树再胜DNN   技术小能手 2018-06-04 14:39:46 浏览848 分布式 性能 神经网络   还记得周志华教授等人的“深度森林”论文吗?今天, ...

  8. mac 下 vscode配置SFTP连接

    VScode中使用SFTP插件连接远程服务器进行文件修改 下载SFTP插件后,使用Ctrl+Shift+P.输入SFTP,选择第一个将会生成简短的默认配置文件 然后把sftp.json文件内内容换成以 ...

  9. c# 粘贴复制

    复制 1. 复制 Clipboard.SetText("123456"); Clipboard.SetImage(Image img); Clipboard.SetAudio(Sy ...

  10. git遇到的问题记录2019.05.07

    用sourcetree拉取代码,报错如下: error: cannot lock ref 'refs/remotes/origin/my_branch': unable to resolve refe ...