Spring容器的初始化
核心方法:
AbstractApplicationContext.refresh()
。
该方法使用了模板方法设计模式,核心步骤:
- prepareRefresh():准备上下文(如切换为启动、处理日志、环境变量校验、初始化监听器与事件)。
- obtainFreshBeanFactory():生成BeanFactory,生成、初始化BeanDefinitionReader、注册BeanDefinition(核心步骤)。
- prepareBeanFactory():配置 BeanFactory(如 ClassLoader、PostProcessor)、注册环境Bean。
- postProcessBeanFactory():子类扩展点(如 WebApplicationContext)。
- invokeBeanFactoryPostProcessors():处理 BeanFactoryPostProcessor。
- registerBeanPostProcessors():注册 BeanPostProcessor。
- initMessageSource():国际化支持。
- initApplicationEventMulticaster():事件广播器。
- onRefresh():子类扩展点(如 ServletWebServerApplicationContext 启动内嵌 Tomcat)。
- registerListeners():注册事件监听器。
- finishBeanFactoryInitialization():初始化所有单例 Bean(核心步骤)。
- finishRefresh():发布 ContextRefreshedEvent 事件。
比较重要的类
AbstractApplicationContext
:实现了应用程序上下文对象(DI容器)的初始化。
BeanFactory
- 定义:创建、配置、初始化、依赖注入、销毁Bean对象。
- 子类:DefaultListableBeanFactory(管理 Bean 定义和实例化流程)、AbstractAutowireCapableBeanFactory(实现 Bean 的创建、依赖注入和初始化)。
BeanDefinitionReader
- 定义:读取和解析Bean定义。
- 子类:XmlBeanDefinitionReader(解析 XML)、AnnotatedBeanDefinitionReader(解析注解)、ClassPathBeanDefinitionScanner(扫描类路径)。
BeanDefinition:描述与管理Bean定义信息。
ResourceLoader
- 定义:用于加载资源。
- 子类:ClassPathResource(类路径资源)、FileSystemResource(文件系统资源)。
Bean的生命周期
1. Bean的实例化前的准备阶段
- 目标:生成Bean实例化所需要的BeanFactory、BeanDefinitionReader、BeanDefinition等类找到 Bean 的配置信息(XML、注解、Java Config 等)。
- 源码入口:容器初始化的第二步骤。
- 生成BeanFactory。
- BeanFactory(本身DefaultListableBeanFactory实现了BeanDefinitionRegistry)装配BeanDefinitionReader
- BeanDefinitionReader中装配ResourceLoader。
- ResourceLoader加载读取配置信息(XML、注解、Java Config 等)并注册BeanDefinition到BeanDefinitionRegistry的beanDefinitionMap中,以bean名称为键的BeanDefinition对象映射表。
如:AbstractXmlApplicationContext.loadBeanDefinitions(DefaultListableBeanFactory beanFactory)。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
注册过程:DefaultListableBeanFactory.registerBeanDefinition()。
// 注册 BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
2. 实例化前的BeanFactoryPostProcessor 处理
- 目标:在 Bean 实例化前修改 BeanDefinition。
- 源码入口:容器初始化的第五步骤。BeanFactoryPostProcessor.postProcessBeanFactory()。
- 触发时机:在 AbstractApplicationContext.refresh() 的 invokeBeanFactoryPostProcessors() 阶段。
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}
/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
.tag("postProcessor", postProcessor::toString);
postProcessor.postProcessBeanFactory(beanFactory);
postProcessBeanFactory.end();
}
}
3. 注册BeanPostProcessor
- 源码入口:容器初始化的第6步骤。
4. Bean 实例化(Instantiation)
- 目标:通过反射或工厂方法创建 Bean 实例。
- 源码入口:容器初始化的第11步骤。AbstractAutowireCapableBeanFactory.createBean()。
- 关键方法:doCreateBean() -> createBeanInstance()。
- 策略:使用 InstantiationStrategy(默认 CglibSubclassingInstantiationStrategy)。
getInstantiationStrategy().instantiate(mbd, beanName, this)
5. 依赖注入(Dependency Injection)属性赋值
- 目标:注入 Bean 的属性和依赖。
- 源码入口:AbstractAutowireCapableBeanFactory.populateBean()。
- 策略:
- 字段注入:通过反射直接设置字段(@Autowired)。
- Setter 注入:调用 Setter 方法。
- 构造器注入:通过构造器参数解析(ConstructorResolver)。
- 关键类:AutowiredAnnotationBeanPostProcessor(处理 @Autowired 和 @Value)。
- 策略:
// 示例:注入依赖
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// 处理 @Autowired 等注解
((InstantiationAwareBeanPostProcessor) bp).postProcessProperties(pvs, bean, beanName);
}
}
6. 初始化(Initialization)
- 目标:调用初始化方法。
- 源码入口:AbstractAutowireCapableBeanFactory.initializeBean()。
- 步骤:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 1. 调用 Aware 接口(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
invokeAwareMethods(beanName, bean); // 直接调用 Aware 方法
}
// 2. 执行 BeanPostProcessor 的前置处理(包括其他 Aware 接口)
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 3. 调用 InitializingBean.afterPropertiesSet() 和 init-method
// ...
return wrappedBean;
}
// 示例:初始化前后的处理
public Object applyBeanPostProcessorsBeforeInitialization(Object bean, String beanName) {
for (BeanPostProcessor processor : getBeanPostProcessors()) {
bean = processor.postProcessBeforeInitialization(bean, beanName);
}
return bean;
}
// 示例:调用初始化方法
if (bean instanceof InitializingBean) {
((InitializingBean) bean).afterPropertiesSet();
}
7. Bean 的销毁(Destruction)
- 目标:容器关闭时销毁 Bean。
- 源码入口:DisposableBeanAdapter.destroy()。
- 触发方式:
- 实现 DisposableBean 接口的 destroy()。
- 配置 destroy-method。
- 关键逻辑:在 AbstractApplicationContext.close() 中调用 destroyBeans()。
- 触发方式:
// 示例:销毁 Bean
if (bean instanceof DisposableBean) {
((DisposableBean) bean).destroy();
}
关键点总结
1. 触发时机
- 单例非懒加载 Bean 的实例化在容器启动时完成(refresh() 的 finishBeanFactoryInitialization() 阶段)。
- 原型(Prototype)或懒加载(Lazy-init)的 Bean 在首次getBean() 调用时实例化。
2. 实例化与初始化的区别
- 实例化(Instantiation):创建 Bean 对象(调用构造器)。
- 初始化(Initialization):填充属性、执行 @PostConstruct、实现InitializingBean接口的afterPropertiesSet() 等逻辑。
流程图解
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)
└─> beanFactory.preInstantiateSingletons()
└─> DefaultListableBeanFactory.preInstantiateSingletons()
└─> AbstractBeanFactory.getBean(beanName)
└─> doGetBean(name, null, null, false)
└─> createBean(beanName, mbd, args)
└─> AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args)
└─> doCreateBean(beanName, mbdToUse, args)
└─> createBeanInstance(beanName, mbd, args) // 实例化
└─> instantiateBean(beanName, mbd)
└─> getInstantiationStrategy().instantiate(mbd, beanName, this)
└─> populateBean(beanName, mbd, instanceWrapper) // 依赖注入
└─> initializeBean(beanName, exposedObject, mbd) // 初始化
└─> invokeAwareMethods(beanName, bean) // aware接口,基础设施引用
└─> applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) // bean前置处理器
└─> invokeInitMethods(beanName, wrappedBean, mbd) // 调用初始化方法
└─> ((InitializingBean) bean).afterPropertiesSet() // 调用设置属性后方法
└─> invokeCustomInitMethod(beanName, bean, mbd) // 调用自定义初始化方法
└─> applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) // bean后置处理器
└─> registerDisposableBeanIfNecessary(beanName, bean, mbd) // 注册需要销毁的bean的方法
Bean的相关应用
1、实例化Bean之前,对bean定义进行扩展或者修改
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 在这里可以修改 bean 的定义,例如:
// 获取到某个 bean 的定义并修改它
BeanDefinition bd = beanFactory.getBeanDefinition("myBean");
bd.getPropertyValues().addPropertyValue("brand", "问界");
System.out.println("BeanFactoryPostProcessor is called");
}
}
2、实例化后,初始化方法前后的处理
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 在初始化方法之前执行的逻辑
System.out.println("Before initialization: " + beanName);
return bean; // 返回bean对象,以便继续后续的初始化过程
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 在初始化方法之后执行的逻辑
System.out.println("After initialization: " + beanName);
return bean; // 返回bean对象,以便继续后续的流程
}
}
3、实例化后,初始化方法
xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- @PostConstruct 需要启动注解 -->
<context:annotation-config />
<!-- 注册myBean的bean,并设置init-method方法 -->
<bean id="myBean" class="org.example.MyBean" init-method="initMethod">
<!-- 设置依赖注入的属性 -->
<property name="message" value="Hello, Spring!" />
</bean>
</beans>
bean的实现
public class MyBean implements InitializingBean {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@PostConstruct
public void initPostConstruct() {
System.out.println("执行MyBean的PostConstruct...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("执行MyBean的初始化方法");
}
//在配置类中利用注解将initMethod指向下面的init方法-对应于initMethod的用法
public void initMethod() {
System.out.println("执行MyBean的init-method...");
}
@PreDestroy
public void destroy() {
// 销毁逻辑
System.out.println("执行MyBean的销毁方法");
}
// 在配置类中利用注解将destroy-method指向下面的destoryMethod
public void destoryMethod() {
System.out.println("执行MyBean的destory-method...");
}
}
执行顺序@PostConstruct -> afterPropertiesSet() -> initMethod()
4、Bean的销毁
xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- @PostConstruct 需要启动注解 -->
<context:annotation-config />
<!-- 注册myBean的bean,并设置init-method方法 -->
<bean id="myBean" class="org.example.MyBean" destroy-method="destoryMethod">
<!-- 设置依赖注入的属性 -->
<property name="message" value="Hello, Spring!" />
</bean>
</beans>
bean的实现
public class MyBean implements InitializingBean {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@PreDestroy
public void destroy() {
// 销毁逻辑
System.out.println("执行MyBean的销毁方法");
}
// 在配置类中利用注解将destroy-method指向下面的destoryMethod
public void destoryMethod() {
System.out.println("执行MyBean的destory-method...");
}
}
执行顺序@PreDestroy->destoryMethod()