Spring源码阅读(一)Bean的创建过程
2025年4月16日 · 1927 字 · 4 分钟 · Spring
实例化 -> 属性填充 -> BeanPostProcessor前置处理 -> 初始化阶段 -> BeanPostProcessor后置处理 -> 初始化完成 -> PostConstruct -> InitializingBean.afterPropertiesSet -> 自定义init-method -> AOP
创建的大致流程
推断构造方法
利用该类的构造方法来实例化得到一个对象(但是如何一个类中有多个构造方法,Spring则会进行选择,这个叫做推断构造方法)
依赖注入
得到一个对象后,Spring会判断该对象中是否存在被@Autowired注解了的属性,把这些属性找出来并由Spring进行赋值(属性填充)
BeanPostProcessor处理和初始化
依赖注入后,Spring会判断该对象是否实现了BeanNameAware
接口、BeanClassLoaderAware
接口、BeanFactoryAware
接口,如果实现了,就表示当前对象必须实现该接口中所定义的setBeanName()
、setBeanClassLoader()
、setBeanFactory()
方法,那Spring就会调用这些方法并传入相应的参数(Aware回调)
PostConstruct 处理
Aware回调后,Spring会判断该对象中是否存在某个方法被@PostConstruct注解了,如果存在,Spring会调用当前对象的此方法(初始化前)
InitializingBean.afterPropertiesSet
紧接着,Spring会判断该对象是否实现了InitializingBean接口,如果实现了,就表示当前对象必须实现该接口中的afterPropertiesSet()方法,那Spring就会调用当前对象中的afterPropertiesSet()方法(初始化)
自定义init-method
执行自定义init-method
AOP
最后,Spring会判断当前对象需不需要进行AOP,如果不需要那么Bean就创建完了,如果需要进行AOP,则会进行动态代理并生成一个代理对象做为Bean(初始化后)
我们可以发现,当Spring根据UserService类来创建一个Bean时:
- 如果不用进行AOP,那么Bean就是UserService类的构造方法所得到的对象。
- 如果需要进行AOP,那么Bean就是UserService的代理类所实例化得到的对象,而不是UserService本身所得到的对象。
Bean对象创建出来后:
- 如果当前Bean是单例Bean,那么会把该Bean对象存入一个Map<String, Object>,Map的key为beanName,value为Bean对象。这样下次getBean时就可以直接从Map中拿到对应的Bean对象了。(实际上,在Spring源码中,这个Map就是单例池)
- 如果当前Bean是原型Bean,那么后续没有其他动作,不会存入一个Map,下次getBean时会再次执行上述创建过程,得到一个新的Bean对象。
初始化入口
AbstractAutowireCapableBeanFactory
// 源码路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 调用Aware接口方法
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执行BeanPostProcessor前置处理(包括@PostConstruct注入)
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 执行InitializingBean和init-method
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException();
}
if (mbd == null || !mbd.isSynthetic()) {
// 执行BeanPostProcessor后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
@PostConstruct 处理机制
InitDestroyAnnotationBeanPostProcessor
// 源码关键路径:org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 获取@PostConstruct元数据
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
// 反射执行初始化方法
metadata.invokeInitMethods(bean, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException();
}
return bean;
}
InitializingBean 处理机制
// 源码路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
if (bean instanceof InitializingBean) {
// 执行接口方法
((InitializingBean) bean).afterPropertiesSet();
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName)) {
// 反射调用自定义init方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
执行顺序与线程安全
BeanPostProcessor.postProcessBeforeInitialization -> PostConstruct -> InitializingBean.afterPropertiesSet -> 自定义init-method -> BeanPostProcessor.postProcessAfterInitialization
核心类
-
InitDestroyAnnotationBeanPostProcessor
- postProcessBeforeInitialization()
- findLifecycleMetadata()
-
AbstractAutowireCapableBeanFactory
- invokeInitMethods()
- invokeCustomInitMethod()
-
CommonAnnotationBeanPostProcessor
- postProcessBeforeInitialization()
@PostConstruct 和 InitializingBean
@PostConstruct 和 InitializingBean 在 Spring 生命周期中扮演着不同的角色:
@PostConstruct
- 基于标准注解的轻量级初始化
- 通过BeanPostProcessor实现
- 支持方法级细粒度控制
InitializingBean
- 框架原生接口方案
- 直接集成到Bean初始化流程
- 提供类型安全的回调
生产环境选择建议
- 80%场景使用@PostConstruct
- 需要强制初始化保障时选择InitializingBean
- 第三方库集成使用init-method