0源码基础学习Spring源码系列(一)——Bean注入流程

打印 上一主题 下一主题

主题 608|帖子 608|积分 1824

作者:京东科技 韩国凯
通过本文,读者可以0源码基础的初步学习spring源码,并能够举一反三从此进入源码世界的大米!
由于是第一次阅读源码,文章之中难免存在一些问题,还望包涵指正!
一、 @Autowired与@Resource的区别

用一句话总结两者的区别就是: @Autowired会先通过类型注入,即byType,当存在有多个类型时会通过名称注入。@Resource则相反,会先通过名称注入,即byName,当名称不存在或有多个名称时会通过类型注入。
那么通过名称注入与通过类型注入有什么区别呢?
  1. //创建接口
  2. interface StuService{
  3.     String getName();
  4. }
  5. @Service
  6. //Stu2实现接口并注册bean
  7. class Stu2 implements StuService{
  8.     @Override
  9.     public String getName() {
  10.         return "stu2";
  11.     }
  12. }
  13. @Service
  14. //Stu3实现接口并注册bean
  15. class Stu3 implements StuService{
  16.     @Override
  17.     public String getName() {
  18.         return "stu3";
  19.     }
  20. }
复制代码
1.1 @Autowired

那么此时如果我们对 StuService注入, @Autowired可以选择注入的类型就有两个,分别是 Stu2与 Stu3。
需要注意的是,类型有很多种选择:

  • 当注册bean与获取bean为同一个类时,类型只有这个类本身。
例如,我们有获取session的工具类,需要将其注入到spring之中,
  1. @Component
  2. class SessionUtil{
  3.     public String getSession(){
  4.         return "session";
  5.     }
  6. }
复制代码
只有一个类,直接注册bean,使用时可以任意选择
  1. @Autowired
  2. SessionUtil sessionUtil;
复制代码
此时@Autowired只有一个注册类型,直接注入。

  • 当注册bean有多个时,类型为所有注册的bean,实现方式有:实现接口、继承、通过其他方式,例如xml配置注册bean。
例如上述 StuService有多个实现类,每个实现类都注册了bean,因此@Autowired可以选择的类型就有两个。
  1. @Autowired
  2. StuService stu;
复制代码
根据上述的@Autowired逻辑,此时有多个类型,那么会根据bean name查找,(即类名首字母小写的),发现 stu没有对应的实现类,
此时会报错:
Field stu in com.example.demo.spring.Stu1 required a single bean, but 2 were found:
只需要将 stu 替换成 stu2或 stu3即可完成注入。
继承和其他方式同时有多个bean注入时同理。
因此,@Autowired中类型的定义可以归结为:当注册bean有多个时,类型为所有注册的bean,实现方式有:实现接口、继承、通过其他方式,例如xml配置注册bean或者@Bean注册。
1.2 @Resource


  • 当只有一个bean时,可以直接注册
  1. @Autowired
  2. SessionUtil sessionUtil;
复制代码

  • 当有多个bean注册时,如果未指定名称,则bean name为类名首字母小写,指定了bean名称则注册名称为该名称。
例如上文中 Stu1 Stu2都未指定bean名称,因此两者的bean名称分别为 stu1 stu2。
当使用@Bean在方法上注册bean,此时名称为方法名称。
  1. @Bean()
  2. public Student getStudent(){
  3.     Student student = new Student();
  4.     student.setName("bob");
  5.     student.setId(26);
  6.     return student;
  7. }
复制代码
此时该bean名称为 getStudent。
同样,我们也可以注册bean时自定义bean名称
  1. @Bean("stu1")
  2. public Student getStudent(){
  3.     Student student = new Student();
  4.     student.setName("bob");
  5.     student.setId(26);
  6.     return student;
  7. }
  8. @Service("stu2")
  9. class Stu2 implements StuService{
  10.     @Override
  11.     public String getName() {
  12.         return "stu2";
  13.     }
  14. }
  15. @Component("stu3")
  16. class Stu3 implements StuService{
  17.     @Override
  18.     public String getName() {
  19.         return "stu3";
  20.     }
  21. }
复制代码
在引用时指定bean:
  1. @Resource(name = "stu2")
  2. private StuService stu1;
复制代码
1.3 @Autowired

当我们使用@Resource时,会根据名称也就是 stu2去查询,此时bean名称只有一个,查到返回
  1. @Resource
  2. private Stu3 stu2;
复制代码
但是在执行时却发现报错:
  1. Bean named 'stu2' is expected to be of type 'com.example.demo.spring.Stu3' but was actually of type 'com.example.demo.spring.Stu2'
复制代码
这是因为只根据了bean名称去查询,却没有根据bean类型,查到的是Stu2类型的bean,但是期望的却是Stu3,因此会发生类型不匹配。
二、SpringIOC的Bean注入流程

spring的注册流程主要包含两个部分:

  • 容器的启动阶段及预热工作
  • Bean的注入流程
先了解一下几个概念:
2.1 概念介绍

2.1.1 配置元数据

存在于磁盘上的项目中用于描述一个bean的数据,可以是xml、properties、yaml等静态文件,也可以是各种注解描述的对应信息,例如@Service、@Component描述的一个bean的信息。
  1. <bean id="role" >
  2.     <property name="id" value="1"/>
  3.     <property name="roleName" value="高级工程师"/>
  4.     <property name="note" value="重要人员"/>
  5. </bean>
复制代码
以上就是一个由xml定义的配置元数据。
2.1.2 BeanDefinition与BeanDefinitionReader

在spring中,无论是那种配置元数据,最终都会转换为BeanDefinition,由BeanDefinition描述要生成并被引用的对象,可以理解为BeanDefinition就是bean的生成模板,或者是bean的说明书,按照BeanDefinition生成bean。
而将配置元数据转换为BeanDefinition的工作就是由BeanDefinitionReader完成的,对于不同的的配置元数据有不同的Reader完成对应的工作,例如有XmlBeanDefinitionReader读取xml配置信息,PropertiesBeanDefinitionReader读取properties配置信息,AnnotatedBeanDefinitionReader读取注解的配置信息。
BeanDefinitionReader的作用就是将磁盘上的文件信息或注解信息转化为内存中用于描述bean的BeanDefinition。
2.1.3 BeanFactoryPostProcessor

BeanFactoryPostProcessor是容器启动阶段Spring提供的一个扩展点,主要负责对注册到BeanDefinitionRegistry中的一个个的BeanDefinition进行一定程度上的修改与替换。例如我们的配置元信息中有些可能会修改的配置信息散落到各处,不够灵活,修改相应配置的时候比较麻烦,这时我们可以使用占位符的方式来配置。例如配置Jdbc的DataSource连接的时候可以这样配置:
  1. <bean id="role" >
  2.     <property name="id" value="1"/>
  3.     <property name="roleName" value="高级工程师"/>
  4.     <property name="note" value="重要人员"/>
  5. </bean><bean id="role" >
  6.     <property name="id" value="1"/>
  7.     <property name="roleName" value="高级工程师"/>
  8.     <property name="note" value="重要人员"/>
  9. </bean><bean id="role" >
  10.     <property name="id" value="1"/>
  11.     <property name="roleName" value="高级工程师"/>
  12.     <property name="note" value="重要人员"/>
  13. </bean><bean id="role" >
  14.     <property name="id" value="1"/>
  15.     <property name="roleName" value="高级工程师"/>
  16.     <property name="note" value="重要人员"/>
  17. </bean><bean id="role" >
  18.     <property name="id" value="1"/>
  19.     <property name="roleName" value="高级工程师"/>
  20.     <property name="note" value="重要人员"/>
  21. </bean>
复制代码
BeanFactoryPostProcessor就会对注册到BeanDefinitionRegistry中的BeanDefinition做最后的修改,替换$占位符为配置文件中的真实的数据。
2.1.4 BeanDefinitionRegistry

一个存储BeanDefinition的地方,存储方式为KV值,key为beanName,value为BeanDefinition。
2.1.5 容器启动阶段

容器的启动阶段相对比较简单,首先会将存在于各处的磁盘上的配置元信息由各自的Reader读取到内存之中,转换成BeanDefinition,然后注册到BeanDefinationRegistry之中,最后由BeanFactoryPostProcessor进行修改与替换。

2.1.6 BeanFactory与FactoryBean

BeanFactory与FactoryBean的名字很像,但是确实两个不同的东西。
根据命名规则来看,BeanFactory是一个Factory,也就是一个存放bean的工厂,在创建bean完成后放到其中,使用是从其中获取。
而FactoryBean则是一个bean,只不过与不同的的bean不同的是他不仅可以创建本身类型的bean,也可以类似于Factory一样创建一层有包装的新的bean。这个Bean可以返回一个新的类型的bean,在返回之前也可以对其进行加工。
  1. @Component
  2. class FactoryBeanDemo implements FactoryBean<Student>{
  3.     @Override
  4.     public Student getObject() {
  5.         return new Student();
  6.     }
  7.     @Override
  8.     public Class<?> getObjectType() {
  9.         return Student.class;
  10.     }
  11. }
复制代码
创建一个FactoryBean只需要实现其接口,并实现其中的两个方法。当我们获取FactoryBean时,会返回其中 getObject()方法返回的对象。而如果想要获取FactoryBean本身,只需要在bean name前加一个"&"符号即可。
  1. @Resource()
  2. private Object factoryBeanDemo;
  3. @GetMapping("/getStu")
  4. private String getBean(){
  5.    
  6.     System.out.println(factoryBeanDemo.getClass());
  7.     return stu2.getName();
  8. }
复制代码
  1. //输出结果
  2. class com.example.demo.domain.Student
复制代码
可以看到获取到的是Student类型。
  1. class com.example.demo.spring.FactoryBeanDemo
复制代码
将获取bean名称假“&”符号:
  1. @Resource(name = "&factoryBeanDemo")
  2. private Object factoryBeanDemo;
复制代码
  1. class com.example.demo.spring.FactoryBeanDemo
复制代码
可以看到获取到的对象变成了FactoryBeanDemo本身。
2.2 Bean注入流程

在容器启动阶段,已经完成了bean的注册。如果该对象是配置成懒加载的方式,那么直到我们向Spring要依赖对象实例之前,其都是以BeanDefinitionRegistry中的一个个的BeanDefinition的形式存在,也就是Spring只有在我们第一次依赖对象的时候才开启相应对象的实例化阶段。而如果我们不是选择懒加载的方式,容器启动阶段完成之后,其中有一个步骤finishBeanFactoryInitialization(),在这一步将立即启动Bean实例化阶段,通过隐式的调用所有依赖对象的getBean方法来实例化所有配置的Bean,完成类的加载。
doGetBean():获取并返回bean
doGetBean()的主要流程有两个:

  • 尝试从缓存中获取bean,如果获取到直接返回。
  • 如果没有获取到则尝试加载bean。
  1. protected  T doGetBean(      String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)      throws BeansException {   String beanName = transformedBeanName(name);   Object beanInstance;   // Eagerly check singleton cache for manually registered singletons.   // 1、查询缓存中是否存在,存在的话直接返回   Object sharedInstance = getSingleton(beanName);   if (sharedInstance != null && args == null) {      if (logger.isTraceEnabled()) {         if (isSingletonCurrentlyInCreation(beanName)) {<bean id="role" >
  2.     <property name="id" value="1"/>
  3.     <property name="roleName" value="高级工程师"/>
  4.     <property name="note" value="重要人员"/>
  5. </bean>logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +<bean id="role" >
  6.     <property name="id" value="1"/>
  7.     <property name="roleName" value="高级工程师"/>
  8.     <property name="note" value="重要人员"/>
  9. </bean>      "' that is not fully initialized yet - a consequence of a circular reference");         }         else {<bean id="role" >
  10.     <property name="id" value="1"/>
  11.     <property name="roleName" value="高级工程师"/>
  12.     <property name="note" value="重要人员"/>
  13. </bean>logger.trace("Returning cached instance of singleton bean '" + beanName + "'");         }      }      // 根据缓存中的bean获取实例,主要是检测如果是FactoryBean类型,则获取其内部的getObject()的bean。(需要先了解FactoryBean的作用)      beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);   }   //2、不存在则创建bean   else {      // Fail if we're already creating this bean instance:      // We're assumably within a circular reference.      if (isPrototypeCurrentlyInCreation(beanName)) {         throw new BeanCurrentlyInCreationException(beanName);      }      // Check if bean definition exists in this factory.      // 2.1 尝试从父类的Factory加载bean      BeanFactory parentBeanFactory = getParentBeanFactory();      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {         // Not found -> check parent.         String nameToLookup = originalBeanName(name);         if (parentBeanFactory instanceof AbstractBeanFactory) {<bean id="role" >
  14.     <property name="id" value="1"/>
  15.     <property name="roleName" value="高级工程师"/>
  16.     <property name="note" value="重要人员"/>
  17. </bean>return ((AbstractBeanFactory) parentBeanFactory).doGetBean(<bean id="role" >
  18.     <property name="id" value="1"/>
  19.     <property name="roleName" value="高级工程师"/>
  20.     <property name="note" value="重要人员"/>
  21. </bean>      nameToLookup, requiredType, args, typeCheckOnly);         }         else if (args != null) {<bean id="role" >
  22.     <property name="id" value="1"/>
  23.     <property name="roleName" value="高级工程师"/>
  24.     <property name="note" value="重要人员"/>
  25. </bean>// Delegation to parent with explicit args.<bean id="role" >
  26.     <property name="id" value="1"/>
  27.     <property name="roleName" value="高级工程师"/>
  28.     <property name="note" value="重要人员"/>
  29. </bean>return (T) parentBeanFactory.getBean(nameToLookup, args);         }         else if (requiredType != null) {<bean id="role" >
  30.     <property name="id" value="1"/>
  31.     <property name="roleName" value="高级工程师"/>
  32.     <property name="note" value="重要人员"/>
  33. </bean>// No args -> delegate to standard getBean method.<bean id="role" >
  34.     <property name="id" value="1"/>
  35.     <property name="roleName" value="高级工程师"/>
  36.     <property name="note" value="重要人员"/>
  37. </bean>return parentBeanFactory.getBean(nameToLookup, requiredType);         }         else {<bean id="role" >
  38.     <property name="id" value="1"/>
  39.     <property name="roleName" value="高级工程师"/>
  40.     <property name="note" value="重要人员"/>
  41. </bean>return (T) parentBeanFactory.getBean(nameToLookup);         }      }      if (!typeCheckOnly) {         markBeanAsCreated(beanName);      }      StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")<bean id="role" >
  42.     <property name="id" value="1"/>
  43.     <property name="roleName" value="高级工程师"/>
  44.     <property name="note" value="重要人员"/>
  45. </bean>.tag("beanName", name);      try {         if (requiredType != null) {<bean id="role" >
  46.     <property name="id" value="1"/>
  47.     <property name="roleName" value="高级工程师"/>
  48.     <property name="note" value="重要人员"/>
  49. </bean>beanCreation.tag("beanType", requiredType::toString);         }         /*         * 2.2 获取RootBeanDefinition:首先会根据beanName获取BeanDefinition,然后将BeanDefinition转换为RootBeanDefinition         * BeanDefinition 接口的实现类有很多,通过不同方式注册到 BeanDefinitionRegistry 中的 BeanDefinition 的类型可能都不太相同。           最终,在通过 BeanDefinition 来创建 bean 的实例时,通常都会调用 getMergedBeanDefinition 来获取到一个 RootBeanDefinition。           所以,RootBeanDefinition 本质上是 Spring 运行时统一的 BeanDefinition 视图。         * */         RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);         checkMergedBeanDefinition(mbd, beanName, args);         // Guarantee initialization of beans that the current bean depends on.         // 2.3 初始化依赖的bean         String[] dependsOn = mbd.getDependsOn();         if (dependsOn != null) {<bean id="role" >
  50.     <property name="id" value="1"/>
  51.     <property name="roleName" value="高级工程师"/>
  52.     <property name="note" value="重要人员"/>
  53. </bean>for (String dep : dependsOn) {<bean id="role" >
  54.     <property name="id" value="1"/>
  55.     <property name="roleName" value="高级工程师"/>
  56.     <property name="note" value="重要人员"/>
  57. </bean>   if (isDependent(beanName, dep)) {<bean id="role" >
  58.     <property name="id" value="1"/>
  59.     <property name="roleName" value="高级工程师"/>
  60.     <property name="note" value="重要人员"/>
  61. </bean>      throw new BeanCreationException(mbd.getResourceDescription(), beanName,<bean id="role" >
  62.     <property name="id" value="1"/>
  63.     <property name="roleName" value="高级工程师"/>
  64.     <property name="note" value="重要人员"/>
  65. </bean><bean id="role" >
  66.     <property name="id" value="1"/>
  67.     <property name="roleName" value="高级工程师"/>
  68.     <property name="note" value="重要人员"/>
  69. </bean>"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");<bean id="role" >
  70.     <property name="id" value="1"/>
  71.     <property name="roleName" value="高级工程师"/>
  72.     <property name="note" value="重要人员"/>
  73. </bean>   }<bean id="role" >
  74.     <property name="id" value="1"/>
  75.     <property name="roleName" value="高级工程师"/>
  76.     <property name="note" value="重要人员"/>
  77. </bean>   registerDependentBean(dep, beanName);<bean id="role" >
  78.     <property name="id" value="1"/>
  79.     <property name="roleName" value="高级工程师"/>
  80.     <property name="note" value="重要人员"/>
  81. </bean>   try {<bean id="role" >
  82.     <property name="id" value="1"/>
  83.     <property name="roleName" value="高级工程师"/>
  84.     <property name="note" value="重要人员"/>
  85. </bean>      getBean(dep);<bean id="role" >
  86.     <property name="id" value="1"/>
  87.     <property name="roleName" value="高级工程师"/>
  88.     <property name="note" value="重要人员"/>
  89. </bean>   }<bean id="role" >
  90.     <property name="id" value="1"/>
  91.     <property name="roleName" value="高级工程师"/>
  92.     <property name="note" value="重要人员"/>
  93. </bean>   catch (NoSuchBeanDefinitionException ex) {<bean id="role" >
  94.     <property name="id" value="1"/>
  95.     <property name="roleName" value="高级工程师"/>
  96.     <property name="note" value="重要人员"/>
  97. </bean>      throw new BeanCreationException(mbd.getResourceDescription(), beanName,<bean id="role" >
  98.     <property name="id" value="1"/>
  99.     <property name="roleName" value="高级工程师"/>
  100.     <property name="note" value="重要人员"/>
  101. </bean><bean id="role" >
  102.     <property name="id" value="1"/>
  103.     <property name="roleName" value="高级工程师"/>
  104.     <property name="note" value="重要人员"/>
  105. </bean>"'" + beanName + "' depends on missing bean '" + dep + "'", ex);<bean id="role" >
  106.     <property name="id" value="1"/>
  107.     <property name="roleName" value="高级工程师"/>
  108.     <property name="note" value="重要人员"/>
  109. </bean>   }<bean id="role" >
  110.     <property name="id" value="1"/>
  111.     <property name="roleName" value="高级工程师"/>
  112.     <property name="note" value="重要人员"/>
  113. </bean>}         }         // Create bean instance.         // 2.4 创建实例         if (mbd.isSingleton()) {<bean id="role" >
  114.     <property name="id" value="1"/>
  115.     <property name="roleName" value="高级工程师"/>
  116.     <property name="note" value="重要人员"/>
  117. </bean>sharedInstance = getSingleton(beanName, () -> {<bean id="role" >
  118.     <property name="id" value="1"/>
  119.     <property name="roleName" value="高级工程师"/>
  120.     <property name="note" value="重要人员"/>
  121. </bean>   try {<bean id="role" >
  122.     <property name="id" value="1"/>
  123.     <property name="roleName" value="高级工程师"/>
  124.     <property name="note" value="重要人员"/>
  125. </bean>      //返回真正的bean<bean id="role" >
  126.     <property name="id" value="1"/>
  127.     <property name="roleName" value="高级工程师"/>
  128.     <property name="note" value="重要人员"/>
  129. </bean>      return createBean(beanName, mbd, args);<bean id="role" >
  130.     <property name="id" value="1"/>
  131.     <property name="roleName" value="高级工程师"/>
  132.     <property name="note" value="重要人员"/>
  133. </bean>   }<bean id="role" >
  134.     <property name="id" value="1"/>
  135.     <property name="roleName" value="高级工程师"/>
  136.     <property name="note" value="重要人员"/>
  137. </bean>   catch (BeansException ex) {<bean id="role" >
  138.     <property name="id" value="1"/>
  139.     <property name="roleName" value="高级工程师"/>
  140.     <property name="note" value="重要人员"/>
  141. </bean>      // Explicitly remove instance from singleton cache: It might have been put there<bean id="role" >
  142.     <property name="id" value="1"/>
  143.     <property name="roleName" value="高级工程师"/>
  144.     <property name="note" value="重要人员"/>
  145. </bean>      // eagerly by the creation process, to allow for circular reference resolution.<bean id="role" >
  146.     <property name="id" value="1"/>
  147.     <property name="roleName" value="高级工程师"/>
  148.     <property name="note" value="重要人员"/>
  149. </bean>      // Also remove any beans that received a temporary reference to the bean.<bean id="role" >
  150.     <property name="id" value="1"/>
  151.     <property name="roleName" value="高级工程师"/>
  152.     <property name="note" value="重要人员"/>
  153. </bean>      destroySingleton(beanName);<bean id="role" >
  154.     <property name="id" value="1"/>
  155.     <property name="roleName" value="高级工程师"/>
  156.     <property name="note" value="重要人员"/>
  157. </bean>      throw ex;<bean id="role" >
  158.     <property name="id" value="1"/>
  159.     <property name="roleName" value="高级工程师"/>
  160.     <property name="note" value="重要人员"/>
  161. </bean>   }<bean id="role" >
  162.     <property name="id" value="1"/>
  163.     <property name="roleName" value="高级工程师"/>
  164.     <property name="note" value="重要人员"/>
  165. </bean>});<bean id="role" >
  166.     <property name="id" value="1"/>
  167.     <property name="roleName" value="高级工程师"/>
  168.     <property name="note" value="重要人员"/>
  169. </bean>beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);         }   }   return adaptBeanInstance(name, beanInstance, requiredType);}
复制代码
2.2.1 mbd = getMergedLocalBeanDefinition(beanName)获取BeanDefinition

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
BeanDefinition 接口的实现类有很多,通过不同方式注册到 BeanDefinitionRegistry 中的 BeanDefinition 的类型可能都不太相同。
最终,在通过 BeanDefinition 来创建 bean 的实例时,通常都会调用 getMergedBeanDefinition 来获取到一个 RootBeanDefinition。所以,RootBeanDefinition 本质上是 Spring 运行时统一的 BeanDefinition 视图。
此处就是将各种BeanDefinition统一转换为spring能识别的RootBeanDefinition。
2.2.2 getSingleton(String beanName, ObjectFactory singletonFactory) 获取创建好的对象
  1. sharedInstance = getSingleton(beanName, () -> {
  2.    try {
  3.       //返回真正的bean
  4.       return createBean(beanName, mbd, args);
  5.    }
  6.    catch (BeansException ex) {
  7.       // Explicitly remove instance from singleton cache: It might have been put there
  8.       // eagerly by the creation process, to allow for circular reference resolution.
  9.       // Also remove any beans that received a temporary reference to the bean.
  10.       destroySingleton(beanName);
  11.       throw ex;
  12.    }
  13. });
复制代码
从getSingleton()方法中获取创建好的对象
  1. //获取singletonFactory返回的结果
  2. singletonObject = singletonFactory.getObject();
复制代码
getSingleton()方法中最主要的一次调用也就是从singletonFactory中获取对象,而获取对象的结果就是上面代码中传入的匿名工厂返回的结果,也就是 createBean(beanName, mbd, args)
2.2.3 createBean(beanName, mbd, args) 创建bean
  1. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)      throws BeanCreationException {   if (logger.isTraceEnabled()) {      logger.trace("Creating instance of bean '" + beanName + "'");   }   RootBeanDefinition mbdToUse = mbd;   // Make sure bean class is actually resolved at this point, and   // clone the bean definition in case of a dynamically resolved Class   // which cannot be stored in the shared merged bean definition.   // 1.解析bean class   Class resolvedClass = resolveBeanClass(mbd, beanName);   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {      mbdToUse = new RootBeanDefinition(mbd);      mbdToUse.setBeanClass(resolvedClass);   }   // Prepare method overrides.   // 2.准备覆盖的方法   try {      mbdToUse.prepareMethodOverrides();   }   catch (BeanDefinitionValidationException ex) {      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),<bean id="role" >
  2.     <property name="id" value="1"/>
  3.     <property name="roleName" value="高级工程师"/>
  4.     <property name="note" value="重要人员"/>
  5. </bean>beanName, "Validation of method overrides failed", ex);   }   try {      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.      // 3.尝试返回代理创建的Bean,这个作用就是查找bean中所有实现前置和后置处理器的接口,有没有手工创建然后返回的,代替了spring的创建bean的流程      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);      if (bean != null) {         return bean;      }   }   catch (Throwable ex) {      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,<bean id="role" >
  6.     <property name="id" value="1"/>
  7.     <property name="roleName" value="高级工程师"/>
  8.     <property name="note" value="重要人员"/>
  9. </bean>"BeanPostProcessor before instantiation of bean failed", ex);   }   try {      //4.真正创建bean      Object beanInstance = doCreateBean(beanName, mbdToUse, args);      if (logger.isTraceEnabled()) {         logger.trace("Finished creating instance of bean '" + beanName + "'");      }      return beanInstance;   }   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {      // A previously detected exception with proper bean creation context already,      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.      throw ex;   }   catch (Throwable ex) {      throw new BeanCreationException(<bean id="role" >
  10.     <property name="id" value="1"/>
  11.     <property name="roleName" value="高级工程师"/>
  12.     <property name="note" value="重要人员"/>
  13. </bean>mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);   }}
复制代码
创建bean主要有以下几步:

  • 解析bean的class文件,为后面的根据class文件通过反射创建对象做准备。
  • 预处理bean的Override属性,预处理的方式也比较简单,就是在方法prepareMethodOverride中判断一下,如果lookup-method标签或者replaced-method标签中配置了bean中需要覆盖的方法,就将MethodOverride中的overload属性值设置为false。
  • 尝试通过反射获取被代理的bean。
  • 真正创建bean的过程
2.2.4 Object beanInstance = doCreateBean(beanName, mbdToUse, args) 开始创建bean

以上流程都是获取bean前的流程或获取bean的准备,doCreateBean是真正的创建并填充bean的流程(去掉了一些不重要的代码)。
  1. protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)      throws BeanCreationException {   // Instantiate the bean.   BeanWrapper instanceWrapper = null;   if (mbd.isSingleton()) {      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);   }   if (instanceWrapper == null) {      //1.通过反射创建实例化对象,并将其放入wraaper中。wraaper可以理解为bean的包装对象,里面是bean实例的,还有一些其他bean的属性方便使用      instanceWrapper = createBeanInstance(beanName, mbd, args);   }   Object bean = instanceWrapper.getWrappedInstance();   Class beanType = instanceWrapper.getWrappedClass();   if (beanType != NullBean.class) {      mbd.resolvedTargetType = beanType;   }   // Allow post-processors to modify the merged bean definition.   //2.允许后处理处理器修改合并后的bean定义,这里只是解析这些@Autowired @Value @Resource @PostConstruct等这些注解,并没有发生实际属性注入的动作   synchronized (mbd.postProcessingLock) {      if (!mbd.postProcessed) {         try {<bean id="role" >
  2.     <property name="id" value="1"/>
  3.     <property name="roleName" value="高级工程师"/>
  4.     <property name="note" value="重要人员"/>
  5. </bean>applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);         }         mbd.postProcessed = true;      }   }   // Eagerly cache singletons to be able to resolve circular references   // even when triggered by lifecycle interfaces like BeanFactoryAware.   //3.是否需要提前曝光,用来解决循环依赖时使用   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&         isSingletonCurrentlyInCreation(beanName));   if (earlySingletonExposure) {      if (logger.isTraceEnabled()) {         logger.trace("Eagerly caching bean '" + beanName +<bean id="role" >
  6.     <property name="id" value="1"/>
  7.     <property name="roleName" value="高级工程师"/>
  8.     <property name="note" value="重要人员"/>
  9. </bean>   "' to allow for resolving potential circular references");      }      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));   }   // Initialize the bean instance.   Object exposedObject = bean;   //4.将实例化完成成的bean填充属性   populateBean(beanName, mbd, instanceWrapper);   //5.调用初始化方法,例如 init-method   exposedObject = initializeBean(beanName, exposedObject, mbd);       //6.循环依赖检查   if (earlySingletonExposure) {      Object earlySingletonReference = getSingleton(beanName, false);      if (earlySingletonReference != null) {         if (exposedObject == bean) {<bean id="role" >
  10.     <property name="id" value="1"/>
  11.     <property name="roleName" value="高级工程师"/>
  12.     <property name="note" value="重要人员"/>
  13. </bean>exposedObject = earlySingletonReference;         }         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {<bean id="role" >
  14.     <property name="id" value="1"/>
  15.     <property name="roleName" value="高级工程师"/>
  16.     <property name="note" value="重要人员"/>
  17. </bean>String[] dependentBeans = getDependentBeans(beanName);<bean id="role" >
  18.     <property name="id" value="1"/>
  19.     <property name="roleName" value="高级工程师"/>
  20.     <property name="note" value="重要人员"/>
  21. </bean>Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);<bean id="role" >
  22.     <property name="id" value="1"/>
  23.     <property name="roleName" value="高级工程师"/>
  24.     <property name="note" value="重要人员"/>
  25. </bean>for (String dependentBean : dependentBeans) {<bean id="role" >
  26.     <property name="id" value="1"/>
  27.     <property name="roleName" value="高级工程师"/>
  28.     <property name="note" value="重要人员"/>
  29. </bean>   if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {<bean id="role" >
  30.     <property name="id" value="1"/>
  31.     <property name="roleName" value="高级工程师"/>
  32.     <property name="note" value="重要人员"/>
  33. </bean>      actualDependentBeans.add(dependentBean);<bean id="role" >
  34.     <property name="id" value="1"/>
  35.     <property name="roleName" value="高级工程师"/>
  36.     <property name="note" value="重要人员"/>
  37. </bean>   }<bean id="role" >
  38.     <property name="id" value="1"/>
  39.     <property name="roleName" value="高级工程师"/>
  40.     <property name="note" value="重要人员"/>
  41. </bean>}         }      }   }   // Register bean as disposable.   //7.注册bean   try {      registerDisposableBeanIfNecessary(beanName, bean, mbd);   }   catch (BeanDefinitionValidationException ex) {      throw new BeanCreationException(<bean id="role" >
  42.     <property name="id" value="1"/>
  43.     <property name="roleName" value="高级工程师"/>
  44.     <property name="note" value="重要人员"/>
  45. </bean>mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);   }   return exposedObject;}
复制代码
从上述流程中可以看到,我们创建一个bean主要有以下几个流程:

  • 首先通过class根据反射创建对象,此时该对象的所有的属性都为空,可以理解为我们new出的空属性对象。
  • 解析@Autowired @Value @Resource @PostConstruct这些注解,但并没有发生属性注入的行为。
  • 是否需要提前曝光,用来解决循环依赖时使用,主要作用是如果需要代理会返回代理对象,如果不需要代理,返回前面创建的对象
  • 将第一步实例化完成的空属性对象填充属性,其中如果该bean依赖了其他bean,也会在此步骤将依赖的bean装配,如果bean已经被创建,则直接属性注入,如果不存在,则创建bean,创建方式跟本bean相同,可以理解为递归。
  • 将实例化完成的bean对象初始化,主要查看bean是否实现了一些前置或后置或初始化的方法,如果是的话就执行。
  • 循环依赖检查。
  • 根据scope注册bean。
可以看到,经过以上的几个步骤,我们就获取到了一个实例bean。
其中最重要的三个方法:

  • 实例化bean
  • 装配属性
  • 初始化bean
2.2.5 总结

总结来说,创建bean的流程就是先根据反射获取对象,然后填充对象的属性,初始化,最后将bean注册。

2.3 创建bean流程深入理解

上文我们只粗略的讲解了创建bean的过程,并没有深入的查看源码是如何实现的,例如通过反射获取对象是怎么获取的,填充属性是如何填充的,下文将详细阐述2.2.5过程中在源码层面是如何构建的。
2.3.1 instanceWrapper = createBeanInstance(beanName, mbd, args) 获取实例化对象

该方法通过反射获取实例化的空属性对象。
  1. protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {   // Make sure bean class is actually resolved at this point.   //1.1解析class   Class beanClass = resolveBeanClass(mbd, beanName);   //1.2确认public权限   if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {      throw new BeanCreationException(mbd.getResourceDescription(), beanName,<bean id="role" >
  2.     <property name="id" value="1"/>
  3.     <property name="roleName" value="高级工程师"/>
  4.     <property name="note" value="重要人员"/>
  5. </bean>"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());   }   //2.如果存在 Supplier 回调,则调用 obtainFromSupplier() 进行初始化,因为反射获取对象的效率比较低   Supplier instanceSupplier = mbd.getInstanceSupplier();   if (instanceSupplier != null) {      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) {         /*         * 3.如果args为空且方法已经被resolved,则会直接选择对应的构造方法         * mbd.resolvedConstructorOrFactoryMethod的赋值在下方【1】【2】的代码中赋值         * */         if (mbd.resolvedConstructorOrFactoryMethod != null) {<bean id="role" >
  6.     <property name="id" value="1"/>
  7.     <property name="roleName" value="高级工程师"/>
  8.     <property name="note" value="重要人员"/>
  9. </bean>resolved = true;<bean id="role" >
  10.     <property name="id" value="1"/>
  11.     <property name="roleName" value="高级工程师"/>
  12.     <property name="note" value="重要人员"/>
  13. </bean>autowireNecessary = mbd.constructorArgumentsResolved;         }      }   }   if (resolved) {      if (autowireNecessary) {         return autowireConstructor(beanName, mbd, null, null);      }      else {         return instantiateBean(beanName, mbd);      }   }   // Candidate constructors for autowiring?   //4.自动装配的构造方法   Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {      return autowireConstructor(beanName, mbd, ctors, args);   }   // Preferred constructors for default construction?   //5.是否有首选构造方法   ctors = mbd.getPreferredConstructors();   if (ctors != null) {      return autowireConstructor(beanName, mbd, ctors, null);   }   // No special handling: simply use no-arg constructor.   //6.通过默认的无参构造函数   return instantiateBean(beanName, mbd);}
复制代码

  • 首先解析class文件与确认public权限。
  • 如果存在 Supplier 回调,则调用 obtainFromSupplier() 进行初始化,因为反射获取对象的效率比较低。
  • 如果args为空且使用那个构造函数已经被确定了,则进行标记,后续直接选择使用那种构造方法。
  • 如果args不为空或没有被解析过,则选择使用那种构造方法来构造实例化的对象:
Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
Constructor[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
选择AutowiredAnnotationBeanPostProcessor实现类:
其中重要的代码已贴出:
  1. //1.遍历所有的构造方法for (Constructor candidate : rawCandidates) {   if (!candidate.isSynthetic()) {      nonSyntheticConstructors++;   }   else if (primaryConstructor != null) {      continue;   }   //2.查看当前构造方法是否有@Autowired注解   MergedAnnotation ann = findAutowiredAnnotation(candidate);   if (ann == null) {      Class userClass = ClassUtils.getUserClass(beanClass);      if (userClass != beanClass) {         try {<bean id="role" >
  2.     <property name="id" value="1"/>
  3.     <property name="roleName" value="高级工程师"/>
  4.     <property name="note" value="重要人员"/>
  5. </bean>Constructor superCtor =<bean id="role" >
  6.     <property name="id" value="1"/>
  7.     <property name="roleName" value="高级工程师"/>
  8.     <property name="note" value="重要人员"/>
  9. </bean>      userClass.getDeclaredConstructor(candidate.getParameterTypes());<bean id="role" >
  10.     <property name="id" value="1"/>
  11.     <property name="roleName" value="高级工程师"/>
  12.     <property name="note" value="重要人员"/>
  13. </bean>ann = findAutowiredAnnotation(superCtor);         }         catch (NoSuchMethodException ex) {<bean id="role" >
  14.     <property name="id" value="1"/>
  15.     <property name="roleName" value="高级工程师"/>
  16.     <property name="note" value="重要人员"/>
  17. </bean>// Simply proceed, no equivalent superclass constructor found...         }      }   }   //3.如果有@Autowired注解   if (ann != null) {      //4.如果已经有一个@Autowired注解,则说明存在多个@Autowired注解,则抛出异常      if (requiredConstructor != null) {         throw new BeanCreationException(beanName,<bean id="role" >
  18.     <property name="id" value="1"/>
  19.     <property name="roleName" value="高级工程师"/>
  20.     <property name="note" value="重要人员"/>
  21. </bean>   "Invalid autowire-marked constructor: " + candidate +<bean id="role" >
  22.     <property name="id" value="1"/>
  23.     <property name="roleName" value="高级工程师"/>
  24.     <property name="note" value="重要人员"/>
  25. </bean>   ". Found constructor with 'required' Autowired annotation already: " +<bean id="role" >
  26.     <property name="id" value="1"/>
  27.     <property name="roleName" value="高级工程师"/>
  28.     <property name="note" value="重要人员"/>
  29. </bean>   requiredConstructor);      }      boolean required = determineRequiredStatus(ann);      if (required) {         if (!candidates.isEmpty()) {<bean id="role" >
  30.     <property name="id" value="1"/>
  31.     <property name="roleName" value="高级工程师"/>
  32.     <property name="note" value="重要人员"/>
  33. </bean>throw new BeanCreationException(beanName,<bean id="role" >
  34.     <property name="id" value="1"/>
  35.     <property name="roleName" value="高级工程师"/>
  36.     <property name="note" value="重要人员"/>
  37. </bean>      "Invalid autowire-marked constructors: " + candidates +<bean id="role" >
  38.     <property name="id" value="1"/>
  39.     <property name="roleName" value="高级工程师"/>
  40.     <property name="note" value="重要人员"/>
  41. </bean>      ". Found constructor with 'required' Autowired annotation: " +<bean id="role" >
  42.     <property name="id" value="1"/>
  43.     <property name="roleName" value="高级工程师"/>
  44.     <property name="note" value="重要人员"/>
  45. </bean>      candidate);         }         requiredConstructor = candidate;      }      candidates.add(candidate);   }   //5无参构造函数   else if (candidate.getParameterCount() == 0) {      //将其设置为默认构造函数      defaultConstructor = candidate;   }}//对上面的处理过程进行判断//6.1先检查是否有@Autowired注解if (!candidates.isEmpty()) {   // Add default constructor to list of optional constructors, as fallback.   if (requiredConstructor == null) {      if (defaultConstructor != null) {         candidates.add(defaultConstructor);      }      else if (candidates.size() == 1 && logger.isInfoEnabled()) {         logger.info("Inconsistent constructor declaration on bean with name '" + beanName +<bean id="role" >
  46.     <property name="id" value="1"/>
  47.     <property name="roleName" value="高级工程师"/>
  48.     <property name="note" value="重要人员"/>
  49. </bean>   "': single autowire-marked constructor flagged as optional - " +<bean id="role" >
  50.     <property name="id" value="1"/>
  51.     <property name="roleName" value="高级工程师"/>
  52.     <property name="note" value="重要人员"/>
  53. </bean>   "this constructor is effectively required since there is no " +<bean id="role" >
  54.     <property name="id" value="1"/>
  55.     <property name="roleName" value="高级工程师"/>
  56.     <property name="note" value="重要人员"/>
  57. </bean>   "default constructor to fall back to: " + candidates.get(0));      }   }  //返回@Autowired注解的构造方法   candidateConstructors = candidates.toArray(new Constructor[0]);}//6.2如果只有一个有参构造函数,则返回该有参函数else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {   candidateConstructors = new Constructor[] {rawCandidates[0]};}//6.3对于非Kotlin类只会返回null,所以这里不会进入else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&      defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {   candidateConstructors = new Constructor[] {primaryConstructor, defaultConstructor};}else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {   candidateConstructors = new Constructor[] {primaryConstructor};}else {   //6.4对于不能识别的场景会进入到这里,例如有多个构造函数但是并没有指定@Autowired注解或者没有构造函数(java会帮我们生成一个无参的构造函数),返回null   candidateConstructors = new Constructor[0];}
复制代码
2-5步会对所有的构造函数进行检查,并在检查完进行标记,并会在第6步对标记的结果进行返回,按照ifelse判断顺序主要分为以下几种情况:

  • 如果有@Autowired注解的方法则返回该构造方法
  • 如果只有一个有参构造函数则会返回该有参构造函数
  • 对于不能识别的场景会进入到这里,例如有多个构造函数但是并没有指定@Autowired注解或者没有构造函数(java会帮我们生成一个无参的构造函数)会返回null
在获取到需要的构造函数后,会进行标记,下次不用再次解析可以直接选用那个构造函数,即上文的第4步

  • 是否有首选的构造函数
  • 如果都没有的话,通过默认的无参构造函数创建对象。
我们查看代码发现,无论第4步返回什么结果,最终会执行以下两个方法:
autowireConstructor()与instantiateBean()
两者都会调用
instantiate()方法
最终都会执行以下这个方法
BeanUtils.instantiateClass(constructorToUse)
也就是如下的代码
  1. for (int i = 0 ; i < args.length; i++) {
  2.    if (args[i] == null) {
  3.       Class<?> parameterType = parameterTypes[i];
  4.       argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
  5.    }
  6.    else {
  7.       argsWithDefaultValues[i] = args[i];
  8.    }
  9. }
  10. return ctor.newInstance(argsWithDefaultValues);
复制代码
其中最重要的一句:
return ctor.newInstance(argsWithDefaultValues);
可以发现,也就是这里通过反射的方式创建了一个空属性对象,并一层层返回,直到后面的属性装配等过程,可以说这里就是bean加载过程的源头。
2.3.2 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName) 解析各种注解

该方法主要解析该bean所相关的注解,例如属性有@Resource,bean中@PostConstruct注解都会被解析。
  1. for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
  2.    processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
  3. }
复制代码
processor主要有两个实现类:

  • AutowiredAnnotationBeanPostProcessor 处理@Autowired和@Value注解bean定义信息
  • CommonAnnotationBeanPostProcessor 处理@Resource、@PostConstruct、@PreDestroy注解的bean定义信息
这里需要注意的是,该方法只是会解析并不会真正的进行注入,因为学习意义不大,并不在赘述。
2.3.3 populateBean(beanName, mbd, instanceWrapper) 对实例化完成的bean进行属性注入
  1. //遍历所有的属性
  2. for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
  3.    //对属性进行装填
  4.    PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
  5.    if (pvsToUse == null) {
  6.       if (filteredPds == null) {
  7.          filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  8.       }
  9.       pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
  10.       if (pvsToUse == null) {
  11.          return;
  12.       }
  13.    }
  14.    pvs = pvsToUse;
  15. }
复制代码
其中 bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName)有几个实现方法,比较重要的是:

  • AutowiredAnnotationBeanPostProcessor,主要装配属性是@Autowired与@Value的属性
  • CommonAnnotationBeanPostProcessor,主要装配属性是@Resource的属性
两者最终都会进入如下方法:
  1. //判断要注入的是属性还是方法
  2. if (this.isField) {
  3.    Field field = (Field) this.member;
  4.    ReflectionUtils.makeAccessible(field);
  5.    //如果是属性的话则直接注入
  6.    field.set(target, getResourceToInject(target, requestingBeanName));
  7. }
  8. else {
  9.    if (checkPropertySkipping(pvs)) {
  10.       return;
  11.    }
  12.    try {
  13.       Method method = (Method) this.member;
  14.       ReflectionUtils.makeAccessible(method);
  15.       //否则通过反射注入
  16.       method.invoke(target, getResourceToInject(target, requestingBeanName));
  17.    }
  18.    catch (InvocationTargetException ex) {
  19.       throw ex.getTargetException();
  20.    }
  21. }
复制代码
理解起来比较简单,判断是方法注入还是属性注入,在注入时注入的对象为:
getResourceToInject(target, requestingBeanName)
找到ResourceElement的实现方法中getResource()方法:
返回了 autowireResource(this.resourceFactory, element, requestingBeanName)
  1. if (factory instanceof AutowireCapableBeanFactory) {
  2.    AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
  3.    DependencyDescriptor descriptor = element.getDependencyDescriptor();
  4.    if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
  5.       autowiredBeanNames = new LinkedHashSet<>();
  6.       resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
  7.       if (resource == null) {
  8.          throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
  9.       }
  10.    }
  11.    else {
  12.       resource = beanFactory.resolveBeanByName(name, descriptor);
  13.       autowiredBeanNames = Collections.singleton(name);
  14.    }
  15. }
  16. else {
  17.    resource = factory.getBean(name, element.lookupType);
  18.    autowiredBeanNames = Collections.singleton(name);
  19. }
复制代码
在这个方法中,无论是if还是else,最终都会调用
  1. getBean(name, element.lookupType)
复制代码
也就是我们bean注入的入口,这个过程很像递归,在我们创建bean时,如果发现我们有依赖的其他bean,那么就会去创建依赖的bean,如果依赖的bean还有其依赖的属性则又会去创建被依赖的属性,只到最终全部创建完成,返回一开始想要创建的bean。
2.3.4 exposedObject = initializeBean(beanName, exposedObject, mbd)初始化bean

在该方法中,会对已经填充过属性的bean进行初始化:
  1. Object wrappedBean = bean;
  2. if (mbd == null || !mbd.isSynthetic()) {
  3.    //对bean的前置处理,其中@PostConstruct就在此步骤中
  4.    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  5. }
  6. try {
  7.    //调用初始化方法如果bean实现了InitializingBean接口,则先执行InitializingBean接口的afterPropertiesSet方法,然后执行xml或注解设置的init-method方法。
  8.    invokeInitMethods(beanName, wrappedBean, mbd);
  9. }
  10. catch (Throwable ex) {
  11.    throw new BeanCreationException(
  12.          (mbd != null ? mbd.getResourceDescription() : null),
  13.          beanName, "Invocation of init method failed", ex);
  14. }
  15. if (mbd == null || !mbd.isSynthetic()) {
  16.    //对bean进行后置处理,对象的代理发生在此步骤中
  17.    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  18. }
复制代码
在初始化bean的时候,主要分为三个部分,分别是applyBeanPostProcessorsBeforeInitialization、invokeInitMethods、applyBeanPostProcessorsAfterInitialization,分别对应于初始化的前置处理、自定义init方法、后置处理。
applyBeanPostProcessorsBeforeInitialization、applyBeanPostProcessorsAfterInitialization两个方法的大概逻辑就是获取获取所有实现其接口的类,然后执行其中被覆盖的方法。
常用的注解执行顺序如下:

  • @PostConstruct注解修饰的方法
  • InitializingBean接口的afterPropertiesSet()方法
  • init-method指定的方法
  • @PreDestroy注解修饰的方法
  • DisposableBean接口的destroy()方法
  • destory-method指定的方法
并且在代码中可以看到,前置处理与后置处理都可以改变bean。
在容器启动阶段我们讲到BeanFactoryPostProcessor,这里我们讲到BeanPostProcessor,那么BeanFactoryPostProcessor 和 BeanPostProcessor 有什么区别呢?
BeanFactoryPostProcessor存在于容器启动阶段,而BeanPostProcessor存在于对象实例化阶段,BeanFactoryPostProcessor关注对象被创建之前那些配置的修改,而BeanPostProcessor阶段关注对象已经被创建之后的功能增强,替换等操作,这样就很容易区分了。
BeanPostProcessor与BeanFactoryPostProcessor都是Spring在Bean生产过程中强有力的扩展点。Spring中著名的AOP(面向切面编程),其实就是依赖BeanPostProcessor对Bean对象功能增强的。
BeanFactoryPostProcessor主要用于解决实例化之前,对实例的属性进行拓展,而BeanPostProcessor是在实例化之后对对象做的拓展。
2.4 总结

用简单的话描述一下,创建一个bean的过程大概包括三部分:

  • 通过反射实例化bean
  • 属性装配以及填充
  • 初始化,包括init-method、以及其前后三个步骤。其中AOP增强就是发生在初始化之后的applyBeanPostProcessorsAfterInitialization的步骤中。
通过以上的步骤,就可以获得我们可以正常使用的一个bean。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

写过一篇

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表