1. 引言
在Spring框架中,Bean的生命周期是一个至关重要的概念,它涉及了Bean的创建、初始化、使用以及销毁等多个阶段。其中,Bean的实例化作为生命周期的起点,具有举足轻重的地位。以下将对Spring中Bean的实例化过程进行深度解析,结合源码分析,提供更深入的理解。
2. Bean实例化的背景与意义
在Spring的IOC(Inversion of Control,控制反转)容器中,Bean的实例化是容器管理Bean生命周期的第一步。通过实例化,Spring容器能够创建出开发者定义的Bean对象,为后续的依赖注入、初始化等操作奠定基础。因此,对Bean实例化过程的理解,是掌握Spring框架核心机制的关键。
3. Bean实例化的源码分析
- 扫描与解析
- Spring启动时,会根据配置的包路径进行扫描,获取指定路径下的所有类文件。
- 利用
MetadataReaderFactory
解析类文件,得到MetadataReader
对象,该对象包含了类的元数据信息。 - 通过
excludeFilters
和includeFilters
以及条件注解@Conditional
的筛选,确定哪些类需要被Spring容器管理。
- BeanDefinition的创建
BeanDefinition
是Spring框架中描述Bean的元数据信息的接口,具体实现类有RootBeanDefinition
等。- Spring会读取配置文件或注解中的类名、作用域、属性等信息,并设置到
BeanDefinition
对象中。
- 实例化过程
- Spring通过
AbstractBeanFactory
的doGetBean
方法获取Bean实例。 - 如果Bean是单例(
isSingleton()
为true
),则首先尝试从缓存中获取实例。 - 如果缓存中没有,则调用
getSingleton
方法中的lambda
表达式,通过createBean
方法创建Bean实例。createBean
方法内部调用doCreateBean
方法,该方法又调用instantiateBean
方法实际创建Bean实例。instantiateBean
方法使用反射机制调用类的构造函数创建Bean实例。
- 如果Bean是原型(prototype)或其他非单例类型,则每次调用
getBean
时都会重新创建实例。
- Spring通过
以下是简化的源码片段:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) {
// 实例化Bean之前的前置处理
// ...
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 使用指定的构造函数或默认构造函数实例化Bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// ... 依赖注入、初始化等后续步骤 ...
return instanceWrapper.getWrappedInstance();
}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// ... 省略了部分逻辑 ...
// 确定实例化策略:通过构造函数、工厂方法等
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 默认使用无参构造函数实例化
return instantiateBean(beanName, mbd);
}
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
} else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
// ... 省略了部分逻辑 ...
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
- 依赖注入
- 在Bean实例创建后,Spring会根据
BeanDefinition
中配置的依赖关系,通过populateBean
方法进行依赖注入。 - 依赖注入可以通过属性注入、构造函数注入等方式实现。
- 在Bean实例创建后,Spring会根据
- Bean后处理器
- 如果存在Bean后处理器(
BeanPostProcesso
r),则Spring会在Bean实例化之后、初始化之前调用Bean后处理器的postProcessBeforeInitialization
方法。 - 在Bean初始化之后,Spring还会调用Bean后处理器的
postProcessAfterInitialization
方法。
- 如果存在Bean后处理器(
4. 总结
Spring中Bean的实例化过程涉及扫描、解析、创建BeanDefinition
、实例化Bean、依赖注入以及Bean后处理器等多个步骤。这些步骤共同确保了Bean的正确创建和初始化,为Spring框架的IOC容器提供了坚实的基础。通过深入解析这些步骤的源码,能够更好地理解Spring框架的工作原理,从而在实际开发中更好地运用它。
标签:...,实例,mbd,Spring,beanName,Bean,源码 From: https://blog.csdn.net/m0_51176516/article/details/139260858