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

2023年 9月 12日 109.1k 0

一、概述

在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接口来实现,其接口的主要方法为:

image-20230507213741788

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

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

//spring-config.xml




    


      

---
      
//Car.java

public class Car {
    private int maxSpeed ;
    private String brand ;
    private double price ;
  
---
//CarFactoryBean.java
public class CarFactoryBean implements FactoryBean {
    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());
    }
}
  

最后执行的结果为:

image-20230507214400518

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相互循环依赖,会通过以下步骤解决:

  • 对象A实例化前会去查询SingletonObjects,如果没有,将其工厂类后放置到SingletonFactories中,再进行下一步属性赋值,由于依赖对象B,所以需要对象B实例化;
  • 对象B实例化前会去查询SingletonObjects和EarlySingletonObjects,如果没有,将其工厂类后放置到SingletonFactories中,再进行下一步属性赋值,由于依赖对象A,会去查询SingletonFactories,同个getObject()方产生的bean添加到二级缓存EarlySingletonObjects中,同时对象B实例化成功;
  • 对象A在EarlySingletonObjects了,继续进行属性赋值,能够正常属性赋值对象B;
  • 依赖注入成功后会将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 doGetBean(
          String name, @Nullable Class 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) () -> {
             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。
    • 绘制时序图。

    参考资料

  • spring5 源码深度解析----- IOC 之 bean 的初始化:www.cnblogs.com/java-chen-h…
  • 相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论