一、概述
在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相互循环依赖,会通过以下步骤解决:
- 对象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> 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。
- 绘制时序图。
参考资料
- spring5 源码深度解析----- IOC 之 bean 的初始化:https://www.cnblogs.com/java-chen-hao/p/11140043.html