一、概述
在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](https://i-blog.csdnimg.cn/blog_migrate/414eeeb7d6fe5016529a8c73065f653b.png)
- 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