Spring中Bean的创建
Bean注册的总体流程

BeanDefinationReader读取从xml文件中读取配置并构建BeanDefiniton,然后基于别名(id作为key注册到BeanDefinitionRegister注册器,name作为key注册到AliasRegistry注册中心)注册到BeanDefinitonRegister中。
Bean创建时序图

1、调用BeanFacatory.getBean()会触发Bean的实例化
2、DefaultSingletonBeanRegistry中缓存了单例Bean
3、如果没有缓存,则通过AbstractAutowireCapableBeanFactory的createBean方法创建对象(默认利用无参构造器+反射创建)
构造单例Bean的方法
1、AbstractBeanFactory.doGetBean
//AbstractBeanFactory.doGetBean
//判断是否有其他依赖,如果有其他依赖,注册依赖的 bean 并调用 getBean() 方法创建
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
-> DefaultSingletonBeanRegistry.getSingleton(获取缓存的Bean)
-> singletonFactory.getObject()(没有缓存就创建Bean,即调用createBean方法)
-> AbstractAutowireCapableBeanFactory.createBean
//AbstractBeanFactory.doGetBean
//实现singletonFactory.getObject()匿名内部类
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
-> AbstractAutowireCapableBeanFactory.doCreateBean
-> AbstractAutowireCapableBeanFactory.createBeanInstance
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
// 1. 如果是单例,尝试获取对应的BeanWrapper
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 2. bean未实例化,创建 bean 实例
if (instanceWrapper == null) {
/*
* 说明对应的bean还没有创建,用对应的策略(工厂方法、构造函数)创建bean实例,以及简单初始化
*
* 将beanDefinition转成BeanWrapper,大致流程如下:
* 1. 如果存在工厂方法,则使用工厂方法初始化
* 2. 否则,如果存在多个构造函数,则根据参数确定构造函数,并利用构造函数初始化
* 3. 否则,使用默认构造函数初始化
*/
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
// 从BeanWrapper中获取包装的bean实例
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
// 从BeanWrapper获取包装bean的class引用
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// 3. 应用 MergedBeanDefinitionPostProcessor,即执行后置处理器中的MergedBeanDefinitionPostProcessor处理器
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 处理 merged bean,Autowired通过此方法实现诸如类型的解析
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 4. 检查是否需要提前曝光,避免循环依赖,条件:单例 && 允许循环依赖 && 当前bean正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
// 为避免循环依赖,在完成bean实例化之前,将对应的ObjectFactory加入bean的工厂
this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 对bean再一次依赖引用,应用SmartInstantiationAwareBeanPostProcessor
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
//说明一下方法中各个变量的意义
//singletonObjects:用于保存 beanName 和 bean 实例之间的关系
//singletonFactories:用于保存 beanName 和创建 bean 的工厂之间的关系
//earlySingletonObjects:也是保存 beanName 和 bean 实例之间的关系,不同于 singletonObjects,当一个bean的实例放置于其中后,当bean还在创建过程中就可以通过 getBean 方法获取到
//registeredSingletons:用来保存当前所有已注册的 bean
// 5. 初始化bean实例
Object exposedObject = bean;
try {
// 对bean进行填充,将各个属性值注入,如果存在依赖的bean则进行递归初始化
this.populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 初始化bean,调用初始化方法,比如init-method
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
} catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 6. 再次基于依存关系验证是否存在循环依赖
if (earlySingletonExposure) { // 提前曝光
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) { // 只有在检测到循环引用的情况下才会不为null
if (exposedObject == bean) { // exposedObject没有在初始化中被增强
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
// 获取依赖的bean的name
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 检测依赖,记录未完成创建的bean
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
/*
* 因为bean在创建完成之后,其依赖的bean一定是被创建了的
* 如果actualDependentBeans不为空,则说明bean依赖的bean没有完成创建,存在循环依赖
*/
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
// 7. 注册DisposableBean
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
Bean相关方法执行顺序
(1)实例化Bean
(CreateBean方法中调用resolveBeforeInstantiation)
//bean实例化前调用,是对bean定义进行修改的最后机会
1、InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation()方法
(doCreateBean方法中调用createBeanInstance)
2、构造方法–createBeanInstance()
(doCreateBean方法中调用populateBean)
3、populateBean属性注入
4.1、MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)
4、InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation()方法----在createBeanInstance方法之后,populateBean方法中
5、InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues()方法,用来改变bean的属性(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值,postProcessAfterInstantiation如果返回false,则不执行,@Value的实现)
(2)初始化Bean(doCreateBean方法中调用instantiateBean)
6、BeanPostProcessor后置处理器的before–initializeBean>applyBeanPostProcessorsBeforeInitialization
(instantiateBean中的invokeInitMethods方法)
7、InitializingBean–invokeInitMethods>InitializingBean.afterPropertiesSet()
(instantiateBean中的invokeInitMethods方法)
8、init-method(@Bean(initMethod=“init”))–invokeInitMethods>invokeCustomInitMethod
// bean实例化后立即调用,位于属性注入之前
9、BeanPostProcessor后置处理器的after–initializeBean>applyBeanPostProcessorsAfterInitialization
10、DisposableBean接口实现的destroy()方法
11、DefaultSingletonBeanRegistry.destroySingleton销毁bean
Spring@ConditionalOnXX注解
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)该注解表示,如果存在它修饰的类的bean,则不需要再创建这个bean;可以给该注解传入参数例如@ConditionOnMissingBean(name = “example”),这个表示如果name为“example”的bean存在,这该注解修饰的代码块不执行。
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用)
@ConditionalOnProperty(当有配置信息时生效)
本文详细解析Spring框架中Bean的创建与初始化过程,包括Bean的注册、实例化、属性填充、初始化方法调用及销毁等关键步骤。深入探讨了Bean的生命周期管理,以及Spring如何处理循环依赖和依赖注入。

1346

被折叠的 条评论
为什么被折叠?



