目录
- 一、概述
- 二、Bean的后置处理器
- 三、回顾refresh()方法
- 四、Bean的实例化
- 1、AbstractApplicationContext#finishBeanFactoryInitialization()
- 2、DefaultListableBeanFactory#preInstantiateSingletons()
- 3、AbstractBeanFactory#getBean(String name)
- 4、DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)
- 5、AbstractBeanFactory#createBean(String name)
- 6、AbstractBeanFactory#doCreateBean(beanName, mbdToUse, args);
- 7、createBeanInstance(beanName, mbd, args)
- 8、SimplelnstantiationStrategy#instantiate()
- 9、BeanUtils.instantiateClass(constructorToUse);
- 五、总结
一、概述
这篇文章是接上一篇文章《IOC的启动流程(二)-解析配置与注册BeanDefinition》,上一章节我们见到了Spring IOC容器的解析配置与注册BeanDefinition两个大的流程,接来下分析Bean的实例化以及Bean的属性注入流程。这里我在进行对IOC的启动流程再做次简要的概述。
IOC的启动流程依次主要做了这么几件事:
- 创建容器:加载配置文件,创建文件转换器,保存配置文件的地址,然后进行刷新容器。
- 加载配置:将配置文件的经过各种解析器进行加载,从
Resource
对象->Document
对象 - 解析配置:解析
Document
对象中的imposrt、alias、bean,如果是bean
类型会封装成BeanDefinition
对象。 - 注册Bean:就将
BeanDefinition
对象注册到beanDefinitionMap
中。 - 实例化:获取
BeanDefinition
对象,然后实例化真正的Bean
对象. - 属性注入:为当前
Bean
的依赖Bean
进行注入值。 - 初始化:先进行前置处理,调用
Bean
的默认初始化方法,后置处理。 - 注册IOC容器:对返回回来的
Bean
进行注册到IOC容器中。
实例化开始,就是bean的生命周期的范畴了,写到这,就不得不提一下Bean的生命周期了,来接着往下看。
1、Bean的生命周期
具体的生命周期过程:
- bean对象创建(调用无参构造器)
- 给bean对象设置属性
- bean对象初始化之前操作(由bean的后置处理器负责,实现postProcessBeforeInitialization方法)
- bean对象初始化(需要配置bean时指定初始化方法)
- bean对象初始化之后操作(由bean的后置处理器负责,实现postProcessAfterInitialization方法)
- bean对象就绪可以使用
- bean对象销毁(需在配置bean是指定给你销毁方法)
- IOC容器关闭
总结起来就几步,可看到声明周期:
- 实例化
- 依赖注入
- 初始化,需要通过bean的init-method属性指定初始化方法
- 销毁,IOC容器关闭之前,需要通过bean的destroy-method属性指定销毁的方法
注意:
- ConfigurableApplicationContext 是ApplicationContext的子接口,其中扩展了刷新和关闭容器的方法;
- 若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
- 若bean的作用域为多例时,生命周期的前三个步骤会在获取bean时执行.
前面提到了后置处理器,我们看看什么是后置处理器?
二、Bean的后置处理器
Bean的后置处理器有多种,比如实例化后置处理器实现了InstantiationAwareBeanPostProcessor
接口,初始化后置处理器实现了BeanPostProcessor
接口,销毁后置处理器DestructionAwareBeanPostProcessor
等等。
1、Bean的实例化后置处理器
通过实现InstantiationAwareBeanPostProcessor接口,可以在对象创建时注入依赖。例如,子类AutowiredAnnotationBeanPostProcessor用于处理@Autowired和@Value注解的依赖注入。
@Component
public class BeanInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Nullable
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("实例化之前:" + beanName);
return null;
}
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("实例化之后:" + beanName);
return true;
}
@Nullable
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
//System.out.println("属性填充之前:" + beanName);
return null;
}
//在工厂将给定的属性值应用于给定的 bean 之前,对它们进行后处理。允许检查是否满足所有依赖项,例如基于 bean 属性 setter 上的“Required”注释。
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
输出结果:
实例化之前:fileSystemWatcherFactory
实例化之后:fileSystemWatcherFactory
在初始化之前执行,beanName:fileSystemWatcherFactory
在初始化之后执行,beanName:fileSystemWatcherFactory
…
2、Bean的初始化后置处理器
Bean的初始化后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor
接口且配置到IOC容器中,需要注意是,bean后置处理器不是单独针对某个bean生效,而是针对IOC容器中所有bean的初始化前后都会执行。
@Component
public class BeanPostHello implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之前执行,beanName:" + beanName);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在初始化之后执行,beanName:" + beanName);
return bean;
}
}
输出结果:
在初始化之前执行,beanName:org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration
在初始化之后执行,beanName:org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration
在初始化之前执行,beanName:spring.lifecycle-org.springframework.boot.autoconfigure.context.LifecycleProperties
在初始化之后执行,beanName:spring.lifecycle-org.springframework.boot.autoconfigure.context.LifecycleProperties
在初始化之前执行,beanName:lifecycleProcessor
在初始化之后执行,beanName:lifecycleProcessor
......
3、Bean的销毁后置处理器
DestructionAwareBeanPostProcessor
用于在Bean销毁之前进行自定义处理。
@Component
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
System.out.println(beanName + ":销毁之前执行");
}
}
输出结果:
…
mappingJackson2XmlHttpMessageConverter销毁之前执行
jsonComponentModule销毁之前执行
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration销毁之前执行
…
三、回顾refresh()方法
在上一篇章中,把BeanDefinition
对象注册到beanDefinitionMap
中,这意味着AbstractApplicationContext#refresh()
方法的ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
方法执行完成。
[class: AbstractApplicationContext]
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备环境以便刷新。
prepareRefresh();
// 通知子类刷新内部bean工厂。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备一个Bean工厂,以便在此上下文中使用。
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后处理。里面其实啥都没有。
postProcessBeanFactory(beanFactory);
// 调用BeanFactory的后置处理器BeanFactoryPostProcessor,在 bean定义注册之后bean实例化之前调用.
invokeBeanFactoryPostProcessors(beanFactory);
// 注册Bean的后置处理器BeanPostProcessor,在Bean初始化前,后执行
registerBeanPostProcessors(beanFactory);
// 初始化信息源,国际化相关操作。
initMessageSource();
// 初始化此上下文事件广播器。
initApplicationEventMulticaster();
// 空方法,该方法留给子类实现,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
onRefresh();
// 注册监听器
registerListeners();
// 实例化所有剩余的非延迟初始化的单例对象。
finishBeanFactoryInitialization(beanFactory);
// 最后一步,发布相应的事件。
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经创建的单例对象以避免悬挂资源。
destroyBeans();
// 取消容器刷新
cancelRefresh(ex);
// 将异常传递给调用者。
throw ex;
}
finally {
//在Spring框架的核心部分重置常见的反射缓存,因为对于单例Bean,我们可能再也不需要元数据了……
resetCommonCaches();
}
}
}
refresh()
方法主要就是准备容器上下文、创建容器、刷新容器、注册事件广播器、注册监听器、实例化相应对象等一系列操作。
容器创建和配置加载和配置解析和BeanDefinition的注册主要通过obtainFreshBeanFactory
方法来实现对IOC容器的刷新,同时这里面包含了绝大部分的对BeanDefinition
注册相关操作。
然后Bean的实例化和属性注入和初始化和Bean注册到IOC容器主要通过finishBeanFactoryInitialization(beanFactory);
方法完成,这里面也包含了Bean的生命周期的全部流程。
我们从finishBeanFactoryInitialization(beanFactory);
方法点进去,看看spring
是如何完成Bean
的一整个生命周期的。
四、Bean的实例化
1、AbstractApplicationContext#finishBeanFactoryInitialization()
/**
* 完成此上下文中的bean工厂的初始化,
* 初始化所有剩余的singleton bean。
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化此上下文的转换服务。
//检查容器中是否存在名为 CONVERSION_SERVICE_BEAN_NAME 的Bean(默认为 "conversionService")
//如果存在且类型为 ConversionService,则将其设置为Bean工厂的转换服务。
//转换服务用于支持类型转换,例如在注解属性值解析时。
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 如果没有注册任何bean后置处理器(例如PropertyPlaceholderConfigurer bean),则注册一个默认的嵌入式值解析器:此时,主要用于注解属性值的解析。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 获取所有实现了 LoadTimeWeaverAware 接口的Bean名称。遍历这些Bean并提前实例化它们。这些Bean通常用于类加载增强(如字节码织入),提前初始化这些Bean可以确保它们的增强逻辑在其他Bean初始化之前生效。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用Bean工厂的临时 ClassLoader。
// 临时 ClassLoader 通常用于类型匹配阶段,避免类加载冲突。
beanFactory.setTempClassLoader(null);
// 允许缓存所有bean定义元数据,不期望进一步更改。
// 冻结Bean工厂的配置,表示不再期望对Bean定义进行修改。
beanFactory.freezeConfiguration();
// 实例化所有剩余的(非懒加载)单例。
// 这一步确保所有非懒加载的单例Bean在容器启动时被提前创建。
beanFactory.preInstantiateSingletons();
}
完成Bean工厂的初始化,包括设置转换服务、注册值解析器等。提前初始化某些特殊类型的Bean(如 LoadTimeWeaverAware
)。实例化所有剩余的非懒加载单例Bean。
preInstantiateSingletons();
方法的具体应用,是留给DefaultListableBeanFactory
子类的实现。
2、DefaultListableBeanFactory#preInstantiateSingletons()
@Override
public void preInstantiateSingletons() throws BeansException {
//日志记录
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
//迭代一个副本,以允许init方法反过来注册新的bean定义。虽然这可能不是常规工厂引导的一部分,但它在其他方面工作得很好。
//获取所有的bean的定义列表,为了避免在迭代过程中由于动态注册新Bean定义而导致的并发修改问题。
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 实例化非懒加载的单例Bean
for (String beanName : beanNames) {
//获取BeanDefinition的定义
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//遍历所有Bean名称,检查每个Bean是否满足以下条件:不是抽象BeanDefinition(!bd.isAbstract())。是单例BeanDefinition(bd.isSingleton())。不是懒加载 (!bd.isLazyInit())
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果是 FactoryBean 类型,则进一步判断是否需要立即初始化(通过 SmartFactoryBean.isEagerInit() 方法)。
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
//对于 FactoryBean 类型的Bean,首先获取其对应的工厂Bean实例。如果工厂Bean实现了 SmartFactoryBean 接口,则判断是否需要立即初始化(isEagerInit)。如果启用了安全管理器(System.getSecurityManager()),则通过 AccessController.doPrivileged 提升权限来调用 isEagerInit 方法。如果需要立即初始化,则调用 getBean(beanName) 实例化该Bean。
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//从这开始实例化
getBean(beanName);
}
}
}
// 再次遍历所有Bean名称,检查是否有实现了 SmartInitializingSingleton 接口的Bean。如果存在,则调用其 afterSingletonsInstantiated 方法,通知这些Bean所有单例Bean已经完成实例化。如果启用了安全管理器,则通过 AccessController.doPrivileged 提升权限来调用 afterSingletonsInstantiated 方法。
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
确保所有非懒加载的单例Bean在容器启动时被提前实例化。提供一个扩展点(SmartInitializingSingleton),允许开发者在所有单例Bean实例化完成后执行自定义逻辑。
继续点进getBean(beanName);
方法,来到了AbstractBeanFactory#getBean(String name)
,点进doGetBean(name, null, null, false);
方法,来到了AbstractBeanFactory#getBean(String name)
的具体逻辑。
3、AbstractBeanFactory#getBean(String name)
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//得到Bean的名字,如果指定的是别名,将别名转换为规范的 Bean 名称
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//从缓存中获取单利的Bean,对于单利只会创建一次,创建好之后就会缓存到map中
//默认情况下Bean都是迫切加载的,在容器启动的过程中就实例化好缓存到Map中
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
//判断bean是否在 singletonsCurrentlyInCreation set集合中,该集合中存储的是正在创建的单利Bean
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//获取 Bean 实例的对象,主要是完成 FactoryBean 的相关处理
//即:naem是是以 $ 开头 ,就返回FactoryBean工厂
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//代码走到这里,说明单利缓存的map中是没有正在创建的bean。
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//如果缓存中没有单利Bean,但是缓存中有一个多利的Bean,目前正在创建,由于循环依赖问题,抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//得到容器IOC工厂
BeanFactory parentBeanFactory = getParentBeanFactory();
//通过beanName检查,如果容器中不包含这个Bean
//如果容器中没有Bean,沿着继承体系交给父级去找
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
//得到Bean的原始名字,将别名解析为规范名称
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
//根据名字,类型,参数找Bean
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
//委托父工厂去找Bean , 根据名字和参数
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// 无参数 -> 委托给标准的 getBean 方法,根据名字和类型
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
//根据名字找Bean
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//创建Bean是否要类型检查
if (!typeCheckOnly) {
//标记Bean被创建
markBeanAsCreated(beanName);
}
try {
//合并Bean,主要解决Bean继承时子类和父类的公共属性
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//保证当前 bean 所依赖的 bean 的初始化。
String[] dependsOn = mbd.getDependsOn();
//如果当前Bean依赖了其他Bean
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 + "'");
}
//为给定的 bean 注册一个依赖 bean
registerDependentBean(dep, beanName);
try {
//递归,从容器中获取依赖的Bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
//创建单利Bean
if (mbd.isSingleton()) {
//根据Bean名字获取单利Bean,这里是真正创建Bean的地方,通过ObjectFactory创建
//这里是匿名内部类
sharedInstance = getSingleton(beanName, () -> {
try {
//创建Bean
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.
//销毁实例,从缓存的map中清除单利Bean
destroySingleton(beanName);
throw ex;
}
});
//返回bean实例,主要处理FactoryBean相关
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//如果是多例
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
//如果是prototype模式,每次都会创建新的实例
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
//创建指定 Bean 对象实例 ,如果是prototype模式,每次都会创建新的实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//默认实现将原型标记为不再创建
afterPrototypeCreation(beanName);
}
//返回bean实例,主要处理FactoryBean相关
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
//如果不是单利,不是多利,Bean没有 scope属性,则不合法
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
//检查所需类型是否与实际 bean 实例的类型匹配。
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
如果当前是多例,他就走单例的逻辑,如果当前的Bean的定义是单例就走单例的逻辑。
4、DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)
值得注意的一点是,getSingleton(beanName, () -> {return createBean(beanName, mbd, args);})
,这段代码使用了函数式编程,这里先运行了getSingleton()
方法里面的逻辑,里面的singletonFactory
再调用createBean(beanName, mbd, args);
进行创建具有真正意义的Bean,这里的Bean就不是BeanDefinition对象
。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
//检查参数的有效性:
Assert.notNull(beanName, "Bean name must not be null");
//使用 singletonObjects 作为锁对象来同步,确保对单例对象缓存的访问是线程安全的。
synchronized (this.singletonObjects) {
//从单例缓存中获取对应的 bean 实例。如果实例已经存在,则直接返回该实例。
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//防止在单例销毁过程中创建新的单例 bean,避免不一致的状态。
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
//日志记录
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//准备创建单例之前的钩子方法。
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//调用提供的 ObjectFactory 来创建 bean 实例。这个ObjectFactory 调用的是上面createBean(beanName, mbd, args);里面的逻辑创建。
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
//处理 IllegalStateException,检查在异常发生期间单例对象是否已经被创建。
//处理 BeanCreationException,如果有 suppressed 异常,将其记录为相关原因。
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//清理被抑制的异常记录。
//创建单例之后的钩子方法。
afterSingletonCreation(beanName);
}
if (newSingleton) {
//如果创建了新的单例对象,将其注册到单例缓存中。
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
getSingleton
方法在 Spring 框架中负责管理单例 bean 的生命周期,通过 ObjectFactory
延迟加载单例对象,并确保其创建过程是线程安全的。此方法不仅负责实例化,还包括对异常的处理和单例对象的缓存管理,是 Spring IOC
容器中单例管理的核心部分。
4.1、放入缓存池DefaultSingletonBeanRegistry#addSingleton
将createBean(beanName, mbd, args);
创建的Bean返回回来后,就通过addSingleton(beanName, singletonObject);
方法放入单例缓存池中。后续需要Bean
,就直接从这里面拿就是了,但是只适用于单例Bean
。
/**
* 将给定的单例对象添加到此工厂的单例缓存中。
* <p>To be called for eager registration of singletons.
* @param beanName 指定了bean的名称
* @param singletonObject 单例对象
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
//缓存单例对象
this.singletonObjects.put(beanName, singletonObject);
//清理单例工厂缓存
this.singletonFactories.remove(beanName);
//清理早期单例对象缓存:
this.earlySingletonObjects.remove(beanName);
//注册单例名称
this.registeredSingletons.add(beanName);
}
}
我们再来看看单例bean的缓存池,就是一个线程安全的ConcurrentHashMap。
//Cache of singleton objects: bean name to bean instance.
//单例对象的缓存:bean名称到bean实例。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
addSingleton 方法是 Spring 框架中 DefaultSingletonBeanRegistry 类的一部分。这个方法的主要作用是在单例对象被创建后,将其缓存到单例对象的缓存中,并进行相关的清理和管理操作。
5、AbstractBeanFactory#createBean(String name)
我们点进sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}
中的createBean(beanName, mbd, args)
方法,再来看看如何创建的一个Bean
对象。具体的实现是交给AbstractBeanFactory
的实现类AbstractAutowireCapableBeanFactory
来实现。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//如果日志级别设置为 TRACE,记录正在创建 bean 实例的日志信息。
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 类已解析。如果解析的类不能存储在共享的合并 bean 定义中,则克隆 bean 定义并设置解析的类。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//准备方法重写。
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 实例化前后置处理
//通过 BeanPostProcessor 进行实例化前的处理,如果处理器返回一个代理对象,则直接返回该对象。
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 {
//调用 doCreateBean 方法执行 bean 的实际创建过程。
//通过 logger 记录创建完成的日志。
//处理所有在创建过程中可能抛出的异常。
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}
主要的方法:
- resolveBeanClass: 解析 bean 的类信息。 prepareMethodOverrides:
- 准备和验证方法覆盖(主要用于支持 lookup-method 和 replace-method)。
- resolveBeforeInstantiation: 允许 BeanPostProcessor 在实例化之前返回一个代理对象。
- doCreateBean: 负责 bean 的实际创建过程,包括实例化、依赖注入、初始化等。
createBean 方法负责管理 Spring Bean 的创建过程,确保每个 bean 实例在被应用程序使用之前都经过完整的生命周期管理,包括类解析、方法覆盖检查、实例化前后处理、实际实例化和异常处理等过程。它是 Spring 框架中 bean 生命周期管理的重要组成部分,为应用程序提供了灵活的依赖注入和生命周期管理机制。
6、AbstractBeanFactory#doCreateBean(beanName, mbdToUse, args);
doCreateBean
方法负责 bean 的实际创建过程,包括实例化、依赖注入、初始化等。这个方法里面能清楚直接明显看到Bean的生命周期。
这个方法非常重要。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//检查并从缓存中移除工厂实例缓存,用于单例。
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//调用 createBeanInstance 方法实例化 bean。
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
//解析和缓存 bean 的类型。
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
//应用后处理器以修改合并的 bean 定义,确保每个 bean 只处理一次。
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.
//如果允许循环引用,则提前暴露 bean 的早期引用,可能通过创建代理来解决循环依赖。
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 方法进行属性填充(依赖注入)。
populateBean(beanName, mbd, instanceWrapper);
//调用 initializeBean 方法进行初始化,包括应用 BeanPostProcessors。
exposedObject = 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);
}
}
//循环引用检查和处理:
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//注册 bean 为可销毁的对象,以便在容器关闭时进行销毁。
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
//返回最终的 bean 实例(可能是代理对象)。
return exposedObject;
}
doCreateBean
方法是 Spring Bean 生命周期管理的核心,它处理从 bean 实例化到初始化的全过程,包括依赖注入、后处理器应用、解决循环引用和注册销毁回调等。通过这个方法,Spring 确保每个 bean 都能按照配置和依赖正确创建,并在需要时参与到应用程序的生命周期管理中。
这个篇章只写这个方法的实例化。
7、createBeanInstance(beanName, mbd, args)
我们点进instanceWrapper = createBeanInstance(beanName, mbd, args);
方法,来到了AbstractAutowireCapableBeanFactory#createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
方法。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 通过 resolveBeanClass 确保 bean 类在此时已被解析。
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//如果 bean 类不是公共的且配置不允许非公共访问,抛出异常。
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());
}
//如果有 Supplier 提供实例,则通过 obtainFromSupplier 方法获取实例。
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
//如果定义了工厂方法,则通过 instantiateUsingFactoryMethod 方法实例化 bean。
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
//如果构造函数或工厂方法已经解析,检查是否需要自动装配。
//如果需要则通过 autowireConstructor,否则直接实例化。
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
//检查是否有候选构造函数可以用于自动装配。
//如果有,使用构造函数自动装配。
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
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.
//如果没有特殊处理需求,则使用无参构造函数实例化 bean。
return instantiateBean(beanName, mbd);
}
Spring 提供了多种策略来实例化 Bean,主要包括:
- 无参构造函数:这是最常见的方法,通过反射调用无参构造函数来创建 Bean 实例。 工厂方法:通过指定工厂方法来创建 Bean
- 实例,工厂方法可以是静态的也可以是实例方法。 Supplier:从 Spring 5 开始,可以使用 Supplier
- 接口来提供自定义的实例化逻辑。
我们直接看最后一个方法return instantiateBean(beanName, mbd);
instantiateBean
方法是 Spring 框架中 AbstractAutowireCapableBeanFactory
类的一部分,用于实例化一个 bean 对象。这个方法采用一个简单的方式通过无参构造函数来创建 bean 实例。
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
//如果系统中存在安全管理器(System.getSecurityManager() 不为 null),则使用 AccessController.doPrivileged 执行实例化操作。这是为了在受限环境中安全地执行潜在的受限操作。
//getInstantiationStrategy().instantiate(mbd, beanName, this):调用实例化策略的 instantiate 方法来创建 bean 实例。默认的策略通常是使用反射调用无参构造函数。
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
//BeanWrapper:创建一个 BeanWrapper 实例,用于包装新创建的 bean 实例。BeanWrapper 是 Spring 提供的一个工具类,用于对 bean 属性进行操作。
//初始化 BeanWrapper:调用 initBeanWrapper(bw) 初始化 BeanWrapper,通常涉及设置一些默认的属性编辑器,以帮助处理属性的类型转换。
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
instantiateBean
方法是 Spring 框架中用于通过无参构造函数创建bean
实例的基本方法。它利用 InstantiationStrategy
来抽象具体的实例化过程,并通过 BeanWrapper
来管理 bean 实例的属性,这为后续的属性填充和初始化步骤做好准备。此方法确保了在受限环境中安全地执行实例化操作,并为异常情况提供了统一的处理机制。
8、SimplelnstantiationStrategy#instantiate()
我们继续往下点getInstantiationStrategy().instantiate(mbd, beanName, this);
,通过InstantiationStrategy
的实现类SimplelnstantiationStrategy
来调用构造方法实现。
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
//检查 RootBeanDefinition 中是否有方法覆盖(method overrides)。如果没有方法覆盖,则不需要使用 CGLIB 代理来创建 bean。
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
//为了线程安全,使用 constructorArgumentLock 对构造函数的选择进行同步。
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
//如果构造函数还没有解析,则获取 bean 类的无参构造函数。
final Class<?> clazz = bd.getBeanClass();
//如果类是接口或没有找到无参构造函数,则抛出 BeanInstantiationException。
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//使用 BeanUtils.instantiateClass 方法调用选定的构造函数来创建 bean 实例。
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 如果存在方法覆盖,则需要生成一个 CGLIB 子类来实现方法注入。调用 instantiateWithMethodInjection 方法进行处理。
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
这个方法中做了一个判断如果Bean有方法被覆盖,就使用JDK反射来创建Bean的实例,否则使用CGLIB
来实例化。 CGLIB
调用的是子类 CglibSubclassingInstantiationStrategy
来完成的 , 如果一个类没有接口,就只能使用CGLIB
确保在适当的情况下使用最简单的方式来创建 bean 实例,同时支持复杂的场景如方法覆盖,通过使用 CGLIB 来动态生成代理类。这种设计使得 Spring 能够灵活地管理 bean 的创建和生命周期,同时支持多种复杂的 bean 配置需求。
9、BeanUtils.instantiateClass(constructorToUse);
再来看BeanUtils.instantiateClass(constructorToUse);
的方法.
instantiateClass 方法是 Spring 框架中的一个实用方法,用于通过反射调用构造函数来创建类的实例。
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
//检查构造函数的非空性:
Assert.notNull(ctor, "Constructor must not be null");
try {
//调用 makeAccessible 方法确保即使是非公共构造函数也可以被调用。这在反射中是一个常用的步骤,以绕过 Java 的访问控制。
ReflectionUtils.makeAccessible(ctor);
//检查当前环境中是否存在 Kotlin 反射库,并且构造函数的声明类是否是 Kotlin 类型。如果是 Kotlin 类,使用 KotlinDelegate.instantiateClass 方法来处理 Kotlin 特有的实例化需求。
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
//获取构造函数的参数类型数组。
Class<?>[] parameterTypes = ctor.getParameterTypes();
//确保传入的参数数量不超过构造函数参数的数量。
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
//遍历传入的参数数组。如果参数为 null 且对应的参数类型是基本类型,则从 DEFAULT_TYPE_VALUES 中获取默认值。否则,直接使用传入的参数值。
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
//通过无参构造来创建一个实例。。
return ctor.newInstance(argsWithDefaultValues);
}
}
}
五、总结
实例化策略
Spring 提供了多种策略来实例化 Bean,主要包括:
- 无参构造函数:这是最常见的方法,通过反射调用无参构造函数来创建 Bean 实例。 工厂方法:通过指定工厂方法来创建 Bean
- 实例,工厂方法可以是静态的也可以是实例方法。
- Supplier:从 Spring 5 开始,可以使用 Supplier接口来提供自定义的实例化逻辑。
构造函数解析
- 自动装配构造函数:Spring 可以通过构造函数自动装配机制,根据构造函数的参数类型和 Bean 定义中的配置自动选择合适的构造函数
- 参数类型匹配:Spring 通过反射检查构造函数参数类型,并提供适当的参数(包括默认值)进行实例化。
方法覆盖和 CGLIB
- 方法覆盖:Spring 支持通过 CGLIB 动态代理实现方法覆盖(例如 lookup-method 和 replace-method),这需要生成子类来覆盖特定方法。
BeanWrapper
- 属性管理:实例化后,Spring 使用 BeanWrapper 来封装 Bean 实例,以方便后续的属性填充和类型转换。
安全管理
- 安全性:在有安全管理器的环境中,Spring 使用 AccessController.doPrivileged 来执行实例化操作,确保在受限环境中安全地进行反射调用。
解决循环依赖
- 提前暴露引用:为了处理循环依赖,Spring 可在实例化过程中提前暴露 Bean 的引用,允许其他 Bean 注入一个早期引用。
文章结束,喜欢就给个一键三连吧,你的肯定是我最大的动力,点赞上一千我就是脑瘫也出下章