一、概述
本文分析下Spring的Bean是如何创建的,核心关注Bean的“创建”流程。假设我们已经有了一个Bean的定义,而不去纠结Bean的定义(BeanDefinition)是怎么来的,基于此,梳理它的创建过程。本文会结合一些源码讲解,但不会特别详细,只是帮你梳理一个大纲,有兴趣可以结合本文,对spring的源码进行深入分析。
🤔Bean创建的主要步骤
Spring Bean的创建的源码,在AbstractAutowireCapableBeanFactory#doCreateBean方法中实现,主要的几个步骤:
- 实例化(createBeanInstance):通过反射或者工厂方法创建bean的实例。
- 依赖注入(populateBean): 对@Vaue/@Autowired/@Resource等依赖的注入。
- 初始化(initializeBean): 执行bean定义的初始化方法
- 注册销毁方法(registerDisposableBeanIfNecessary),如果bean指定了销毁方法,需要注册销毁方法,以在Spring容器关闭时,执行对应的方法。
二、解析
2.1 实例化(createBeanInstance)
创建bean,spring首先需要实例化这个bean,也就是通过反射或者工厂方法创建bean的实例。核心就是这个createBeanInstance:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// ...忽略一些检查代码...
// 。BeanDefinition定义了supplier属性,使用supplier方法创建
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 。BeanDefinition定义了工厂方法,使用工厂方法创建
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 。之前已经解析过使用哪个构造方法,直接使用
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);
}
}
// 。调用SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors扩展方法,
// 获取候选构造器,如果返回不为null,则使用选定的构造器
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 。候选构造器不为空 || mode = AUTOWIRE_CONSTRUCTOR || 有参数,使用构造器构造
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// BeanDefinition子类可以实现getPreferredConstructors方法,选择更候选构造方法,默认返回null
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 默认使用无参构造器
return instantiateBean(beanName, mbd);
}
大致流程:
- 通过BeanDefinition定义的Supplier或者工厂创建对象。
- 之前已经解析过使用哪个构造方法,直接使用,否则需要解析使用哪个构造方法。
- 调用SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors扩展方法,获取候选构造器,如果返回不为null,则使用选定的构造器。
- 上一步返回的构造器不为null || 构造模式为构造器构造 || 存在参数,则使用构造器构造。
- 如果BeanDefinition子类重写了getPreferredConstructors方法,返回了不为null的候选构造器,使用候选构造器构造。
- 默认使用无参构造器。
PS:
- @Bean注解定义的bean的BeanDefinition,@Bean方法会被转换为一个工厂方法,用于实例化。
- AutowiredAnnotationBeanPostProcessor实现了determineCandidateConstructors方法,用于选定构造函数。
- 存在@Autowired标识的构造器
- required属性为true(默认为true),则使用该构造器,如果有多个为true,报错。
- required属性为false,则作为候选构造器,与默认无参构造器(如果存在)一起返回。
- 无@Autowired标识构造器,但仅有一个构造方法,且参数不为空,返回该构造器。
- 其他返回null。
- 存在@Autowired标识的构造器
autowireConstructor比较复杂,没有深入研究。
2.2 依赖注入(populateBean)
实例化完成后,Spring执行了一个扩展方法,MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法。
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
//每个bean仅处理一次
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;
}
}
注意:这里是加锁了,并且通过BeanDefinition#postProcessed属性,判断是否处理过,也就是说,这个applyMergedBeanDefinitionPostProcessors方法,只会执行一次。
因此,这里适合对BeanDefinition的一些元数据信息进行解析,并缓存(只执行一次)。AutowiredAnnotationBeanPostProcessor(Autowired的注解实现类),就是通过该扩展方法,解析并缓存BeanDefinition的@Autowired、@Value等注解信息。
该扩展方法完成后,包装Bean形成了一个工厂方法,放入了缓存中,用来解决循环依赖问题,不是本文的重点,不纠结。之后就到了重点populateBean方法,用来依赖注入,可以使用xml或者@Autowired/@Resource/@Value等注解,定义依赖的属性。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// ...省略一些检查代码...
// 。执行实例化后的扩展方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 。根据类型或者名字获取需要自动注入的属性,一般这段代码不会走,因为默认的是AUTOWIRE_NO
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
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);
// 。执行InstantiationAwareBeanPostProcessor的postProcessProperties和postProcessPropertyValues方法。
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
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);
}
// 。执行配置的依赖注入
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
大致流程
- 执行实例化后扩展方法,也就是
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation。 - 根据策略查找依赖的属性,一般不会执行,因为默认的注入策略为AUTOWIRE_NO,也就是只会注入xml配置的或者注解修饰的属性。
- 执行InstantiationAwareBeanPostProcessor的postProcessProperties和postProcessPropertyValues方法。
- postProcessProperties,在属性注入前执行,可以修改或者校验属性。PS:AutowiredAnnotationBeanPostProcessor,在这里对Autowired的属性进行注入。
- postProcessPropertyValues,已经被标记废弃,建议使用postProcessProperties替代。
- 对BeanDefinition中配置的属性进行注入。
到这里,我们大概知道了@Autowired是如何实现的了。实现类为AutowiredAnnotationBeanPostProcessor,它实现了
SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors,用于实现优先使用@Autowired修饰的构造方法。MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition,在实例化后,解析Bean有哪些属性/方法,被Autowired注解修改,并缓存起来。InstantiationAwareBeanPostProcessor#postProcessProperties,在populateBean方法中,获取在postProcessMergedBeanDefinition时已经解析的元数据信息,进行依赖注入。
2.3 初始化(initializeBean)
依赖注入之后,Bean就可以执行定义的初始化操作了,那么
🤔Bean如何定义初始化方法
- 在xml或者@Bean注解中使用的init-method属性,指定初始化方法。
- 实现InitializingBean接口的afterPropertiesSet方法。
- 使用@PostConstruct注解指定初始化方法。
初始化方法的入口为AbstractAutowireCapableBeanFactory#initializeBean,源码:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//。如果Bean实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware等接口,注入相关的属性
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
//。执行BeanPostProcessor初始化前置扩展方法,即postProcessBeforeInitialization
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);
}
if (mbd == null || !mbd.isSynthetic()) {
//。执行BeanPostProcessor初始化后置方法,即PostProcessorsAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
流程非常清晰
- 为实现BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口的Bean,注入BeanName/ClassLoader/BeanFactory等属性。注意:
- 此处为
invokeAwareMethods硬编码实现,仅支持以上三个Aware接口。诸如ApplicationContextAware等Aware接口,是ApplicationContextAwareProcessor这个BeanPostProcessor通过postProcessBeforeInitialization(也就是下个步骤)实现的。
- 此处为
- 执行BeanPostProcessor初始化前置扩展方法,即postProcessBeforeInitialization。举栗子:
ApplicationContextAware通过该方法,实现了ApplicationContextAware、ResourceLoaderAware等Aware接口注入;InitDestroyAnnotationBeanPostProcessor通过该方法,实现了@PostConstruct注解。
- 执行初始化方法。注意这里的初始化方法不包括
@PostConstruct,该注解是在上一步实现的。 - 执行BeanPostProcessor初始化后置方法,即PostProcessorsAfterInitialization。举栗子:
AbstractAutoProxyCreator通过该方法,对Bean进行了动态代理。
🤔面试题:@PostConstruct和InitializingBean接口的afterPropertiesSet哪个先执行?
答:@PostConstruct先执行,该注解是InitDestroyAnnotationBeanPostProcessor通过postProcessBeforeInitialization方法在初始化方法之前执行的,自然在初始化方法之前执行。
2.4 注册销毁方法(registerDisposableBeanIfNecessary)
如果bean指定了销毁方法,需要注册销毁方法,以在Spring容器关闭时,执行对应的方法。
🤔Bean如何定义销毁方法
与初始化方法类似
- 在xml或者@Bean注解中使用的destroy-method属性,指定初始化方法。
- 实现DisposableBean接口的afterPropertiesSet()方法。
- 使用@PreDestroy注解指定销毁方法。
registerDisposableBeanIfNecessary方法比较简单,就是判断是否有以上定义的销毁方法,存在,则注册一下(也就是放到map中),用于容器关闭时执行相关方法。
三、小结
到此为止,Spring Bean的创建就分析完成了,可以看到,实例化 -> 依赖注入 -> 初始化这个过程中,Spring提供了大量的BeanPostProcessor扩展方法。那么我们下期,就来分析下,BeanPostProcessor。
参考: