Spring中Bean创建过程之源码分析

简介: Spring中Bean创建过程之源码分析

一、概述

在Spring进行完IoC容器的初始化之后,IoC容器中就拥有了管理Bean的所有信息,在调用BeanFactory的getBean()方法时,或有其他Bean实例依赖时,就会创建出实例来,本文主要分析Bean的生命周期,其生命周期包括:实例化–>属性赋值–>初始化–>销毁

1.实例化: 在Bean实例被调用或被依赖的实例被创建,该Bean实例会被创建,利用该类的构造方法来实例化该类。

2.属性赋值: 当该Bean的属性依赖其他对象时候,比如属性中有被@Autowired注解的属性,会将其他对象的引用赋予给他。

3.初始化: 初始化主要用以进行一些预处理和后处理。

  • Bean创建前后处理器:主要包括BeanPostProcessor一系列方法,在容器启动的时候就调用的方法;
  • Aware类接口实现:主要是通过Aware类的方法,比如BeanNameAware方法等,它能够拿到BeanName等资源,该级别方法是在初始化之前完成;
  • Bean中具体方法:主要通过重写InitializingBean接口中的一些方法来是吸纳,包括初始化和销毁这两个方法;

4.销毁: 当容器被关闭时该Bean会被销毁,销毁前的操作看其时候有定义。

二、创建过程中的常见类

1.BeanFactory和FactoryBean的区别

BeanFactory是生产Bean的工厂类,其工作流程主要包括:定位 -->加载–>注册。

Spring中的Bean可以根据默认你的BeanFactory来生成Bean实例,对于特殊的Bean也可以自定义工厂类来实现,这就可以通过实现FactoryBean接口来实现,其接口的主要方法为:

  • T getObject():根据该工厂类生产的bean实例。
  • Class<?> getObjectType():根据该工厂类生产的实例Class类型。

以下举例说明FactoryBean接口的使用:

//spring-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:P="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="car" class="com.yangnk.test2.CarFactoryBean" P:carInfo="大奔,600,1000000"/>
</beans>
---
//Car.java
public class Car {
    private int maxSpeed ;
    private String brand ;
    private double price ;
---
//CarFactoryBean.java
public class CarFactoryBean implements FactoryBean<Car> {
    private String carInfo ;
    public String getCarInfo(){
        return  this.carInfo;
    }
    public void setCarInfo (String carInfo){
        this.carInfo = carInfo;
    }
    @Override
    public Car getObject() throws Exception {
        Car car = new  Car();
        String[] infos = carInfo.split(",");
        car.setBrand(infos[0]);
        car.setMaxSpeed(Integer.valueOf(infos[1]));
        car.setPrice(Double.valueOf(infos[2]));
        return  car;
    }
    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }
    @Override
    public boolean isSingleton() {
        return true;
    }
---
//SpringTest1.java
  public class SpringTest1 {
    public static void main(String[] args) {
        BeanFactory bf = new XmlBeanFactory( new ClassPathResource("spring-config.xml"));
        Car car = (Car) bf.getBean("car");
        System.out.println("car.toString() = " + car.toString());
    }
}

最后执行的结果为:

2.BeanWrapper

就是Bean的一个包装类,是在属性赋值之后产生的。

三、解决循环依赖

Spring通过三级缓存和提前暴露的思路来解决循环依赖。主要思路是将循环依赖的对象实例放到缓存中,让对方先实例化再进行初始化。三级缓存包括:SingletonObjects、EarlySingletonObjects、SingletonFactories。

1.SingletonObjects: 已经实例化和初始化的bean放到该map中;用于保存beanName和bean实例之间的关系。

2.EarlySingletonObjects: 已经实例化,但是没有初始化的bean放到该map中;也是用以保存beanName和bean实例之间的关系,和SingletonObjects区别是他是通过SingletonFactories生成的,为解决循环依赖,而没有进行初始化的bean。

3.SingletonFactories: 创建bean的factory放到该map中;用以保存beanName和BeanFactory类之间观念的。

如果对象A和对象B相互循环依赖,会通过以下步骤解决:

  1. 对象A实例化前会去查询SingletonObjects,如果没有,将其工厂类后放置到SingletonFactories中,再进行下一步属性赋值,由于依赖对象B,所以需要对象B实例化;
  2. 对象B实例化前会去查询SingletonObjects和EarlySingletonObjects,如果没有,将其工厂类后放置到SingletonFactories中,再进行下一步属性赋值,由于依赖对象A,会去查询SingletonFactories,同个getObject()方产生的bean添加到二级缓存EarlySingletonObjects中,同时对象B实例化成功;
  3. 对象A在EarlySingletonObjects了,继续进行属性赋值,能够正常属性赋值对象B;
  4. 依赖注入成功后会将SingletonFactories和EarlySingletonObjects中的对象删除。

具体的代码实现可以后续源码分析。

四、源码层面分析Bean的创建过程

从getBean()方法开始分析:

public static void main(String[] args) {
   // 创建一个Spring容器
   ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
   User user1 = (User) applicationContext.getBean("user1");
   user1.sayHello();
}

1.实例化阶段

开始创建bean实例,会首先判断是否能从缓存中取值,如果没有的话才会自己创建。在创建过程中会根据类型分为singleton还是prototype区别创建。

//AbstractBeanFactory.java
protected <T> T doGetBean(
      String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
      throws BeansException {
   // name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx
   // name有可能传入进来的是别名,那么beanName就是id
   String beanName = transformedBeanName(name);
   Object beanInstance;
  ...
// Create bean instance.
//my-开始创建bean实例,分为singleton还是prototype
if (mbd.isSingleton()) {
  sharedInstance = getSingleton(beanName, () -> {
    try {
      return createBean(beanName, mbd, args);
    }
    catch (BeansException ex) {
      // Explicitly remove instance from singleton cache: It might have been put there
      // eagerly by the creation process, to allow for circular reference resolution.
      // Also remove any beans that received a temporary reference to the bean.
      destroySingleton(beanName);
      throw ex;
    }
  });
  beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

这一段是解决循环依赖的核心逻辑,其主要逻辑是:先从singletonObject中后去bean,如果获取不到再从earlySingletonObjects中获取,如果都获取不到,则从singletonFactories获取bean对象的ObjectFactory,该类是创建该bean的工厂类,再将该工厂类创建的singletonObject放到earlySingletonObjects中,并且同时创建singletonFactories中的bean。

//DefaultSingletonBeanRegistry
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   // Quick check for existing instance without full singleton lock
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
         synchronized (this.singletonObjects) {
            // Consistent creation of early reference within full singleton lock
            singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
               singletonObject = this.earlySingletonObjects.get(beanName);
               if (singletonObject == null) {
                  ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                  if (singletonFactory != null) {
                     singletonObject = singletonFactory.getObject();
                     this.earlySingletonObjects.put(beanName, singletonObject);
                     this.singletonFactories.remove(beanName);
                  }
               }
            }
         }
      }
   }
   return singletonObject;
}

开始进行实例化,其中resolveBeforeInstantiation(beanName, mbdToUse)是实现AOP的关键,如果该类需要实现AOP代理,通过该方法会返回其代理类。

//AbstractAutowireCapableBeanFactory.java
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.
   // 马上就要实例化Bean了,确保beanClass被加载了
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }
   // Prepare method overrides.
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }
   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      // 实例化前
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }
   try {
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
         logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
---
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
   // 实例化bean
   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      // 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      // 创建Bean实例
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }
   // 后置处理合并后的BeanDefinition
   // Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            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.
   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");
      }
      // 循环依赖-添加到三级缓存
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }
   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      // 属性填充
      populateBean(beanName, mbd, instanceWrapper);
      // 初始化
      exposedObject = initializeBean(beanName, exposedObject, mbd);
     ...

实例化阶段的核心流程,如果有指定构造方法就用指定构造方法,如果没有则用默认构造方法instantiateBean(beanName, mbd),这些生成的结果都保存在BeanWrapper中。

//AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // Make sure bean class is actually resolved at this point.
   Class<?> beanClass = resolveBeanClass(mbd, beanName);
   if (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());
   }
   // BeanDefinition中添加了Supplier,则调用Supplier来得到对象
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }
   // @Bean对应的BeanDefinition
   if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }
   // Shortcut when re-creating the same bean...
   // 一个原型BeanDefinition,会多次来创建Bean,那么就可以把该BeanDefinition所要使用的构造方法缓存起来,避免每次都进行构造方法推断
   boolean resolved = false;
   boolean autowireNecessary = false;
   if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
         if (mbd.resolvedConstructorOrFactoryMethod != null) {
            resolved = true;
            // autowireNecessary表示有没有必要要进行注入,比如当前BeanDefinition用的是无参构造方法,那么autowireNecessary为false,否则为true,表示需要给构造方法参数注入值
            autowireNecessary = mbd.constructorArgumentsResolved;
         }
      }
   }
   if (resolved) {
      // 如果确定了当前BeanDefinition的构造方法,那么看是否需要进行对构造方法进行参数的依赖注入(构造方法注入)
      if (autowireNecessary) {
         // 方法内会拿到缓存好的构造方法的入参
         return autowireConstructor(beanName, mbd, null, null);
      }
      else {
         // 构造方法已经找到了,但是没有参数,那就表示是无参,直接进行实例化
         return instantiateBean(beanName, mbd);
      }
   }
   // 如果没有找过构造方法,那么就开始找了
   // Candidate constructors for autowiring?
   // 提供一个扩展点,可以利用SmartInstantiationAwareBeanPostProcessor来控制用beanClass中的哪些构造方法
   // 比如AutowiredAnnotationBeanPostProcessor会把加了@Autowired注解的构造方法找出来,具体看代码实现会更复杂一点
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   // 如果推断出来了构造方法,则需要给构造方法赋值,也就是给构造方法参数赋值,也就是构造方法注入
   // 如果没有推断出来构造方法,但是autowiremode为AUTOWIRE_CONSTRUCTOR,则也可能需要给构造方法赋值,因为不确定是用无参的还是有参的构造方法
   // 如果通过BeanDefinition指定了构造方法参数值,那肯定就是要进行构造方法注入了
   // 如果调用getBean的时候传入了构造方法参数值,那肯定就是要进行构造方法注入了
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
   }
   // Preferred constructors for default construction?
   ctors = mbd.getPreferredConstructors();
   if (ctors != null) {
      return autowireConstructor(beanName, mbd, ctors, null);
   }
   // No special handling: simply use no-arg constructor.
   // 不匹配以上情况,则直接使用无参构造方法
   return instantiateBean(beanName, mbd);
}

2.属性赋值阶段

开始进行属性赋值,核心方法是populateBean(),其是将BeanDefinition中的属性设置为PropertyValues对象,再把结果保存到BeanWrapper中。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
      if (mbd.hasPropertyValues()) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
        // Skip property population phase for null instance.
        return;
      }
    }
    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    // 实例化之后,属性设置之前
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
        if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
          return;
        }
      }
    }
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      // MutablePropertyValues是PropertyValues具体的实现类
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
        autowireByName(beanName, mbd, bw, newPvs);
      }
      // Add property values based on autowire by type if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
    }
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
      if (pvs == null) {
        pvs = mbd.getPropertyValues();
      }
      for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
        // 这里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法,会直接给对象中的属性赋值
        // AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
        PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
        if (pvsToUse == null) {
          if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
          }
          pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
          if (pvsToUse == null) {
            return;
          }
        }
        pvs = pvsToUse;
      }
    }
    if (needsDepCheck) {
      if (filteredPds == null) {
        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      checkDependencies(beanName, mbd, filteredPds, pvs);
    }
    // 如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowired
    if (pvs != null) {
      applyPropertyValues(beanName, mbd, bw, pvs);
    }
  }

3.初始化阶段

开始进行初始化,主要是通过initializeBean()来实现的,在这个方法中,会实现几个拓展点,包括激活 Aware 方法,实现后置处理器BeanPostProcessors,激活自定义方法invokeInitMethods()。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }
   Object wrappedBean = bean;
   // 初始化前
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }
   // 初始化
   try {
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   // 初始化后 AOP
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

4.销毁阶段

五、创建过程中Bean的扩展点

针对于创建Bean过程中可用的Bean扩展点方式,我做了一下总结:

Aware类接口

  • BeanFactoryAware/ApplicationContextAware:会获取BeanFactory、ApplicationContext,可以对其操作;
  • BeanNameAware:会获取BeanName,可以对其操作;

针对Bean的前置后置处理器

  • BeanPostProcessor:每次实例化Bean后都会调用该接口;
  • InitializingBean:初始化前会调用该接口;
  • DisposableBean:销毁后会调用该接口;

针对Bean中的方法前置后置处理

  • @PostConstruct:构造方法执行完后会执行该方法
  • @PreDestroy:销毁前会执行该方法;

六、总结

TODO

  • 详细说明BeanWrapper。
  • 绘制时序图。

参考资料

  1. spring5 源码深度解析----- IOC 之 bean 的初始化:https://www.cnblogs.com/java-chen-hao/p/11140043.html


目录
相关文章
|
2天前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
10 1
|
2天前
|
XML 前端开发 Java
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
5 0
|
2天前
|
存储 缓存 Java
【JavaEE】Spring中注解的方式去获取Bean对象
【JavaEE】Spring中注解的方式去获取Bean对象
3 0
|
2天前
|
存储 Java 对象存储
【JavaEE】Spring中注解的方式去存储Bean对象
【JavaEE】Spring中注解的方式去存储Bean对象
7 0
|
2天前
|
存储 Java 对象存储
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
9 0
|
2天前
|
消息中间件 安全 Java
在Spring Bean中,如何通过Java配置类定义Bean?
【4月更文挑战第30天】在Spring Bean中,如何通过Java配置类定义Bean?
21 1
|
2天前
|
XML Java 数据格式
Spring Bean
【4月更文挑战第30天】Spring Bean
17 0
|
2天前
|
前端开发 Java 数据格式
【Spring系列笔记】定义Bean的方式
在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。
32 2
|
2天前
|
XML Java 数据格式
谈谈 Spring 中 Bean 的生命周期?
谈谈 Spring 中 Bean 的生命周期?
20 1
|
2天前
|
XML Java 数据格式
Spring Bean的定义(含创建Bean的三种方式)
Spring Bean的定义(含创建Bean的三种方式)