一、Spring项目启动入口解析
1.1 启动类结构与核心注解
Spring Boot项目的入口类通常位于项目根包下,包含main
方法并通过@SpringBootApplication
注解标记。以下是典型启动类代码示例:
@SpringBootApplication
public class SpringLearnApplication {
public static void main(String[] args) {
SpringApplication.run(SpringLearnApplication.class, args);
}
}
核心注解说明:
- @SpringBootApplication:组合了
@Configuration
、@EnableAutoConfiguration
和@ComponentScan
。@Configuration
:标记该类为配置类,替代XML配置@ComponentScan
:自动扫描当前包及子包的组件@EnableAutoConfiguration
:启用自动配置机制,加载spring.factories
中的配置类
1.2 SpringApplication.run方法解析
SpringApplication.run()
方法触发容器初始化流程:
- 创建SpringApplication实例:加载
META-INF/spring.factories
中的ApplicationContextInitializer
和ApplicationListener
- 执行run方法:核心逻辑如下:
public ConfigurableApplicationContext run(String... args) {
// 1. 启动计时器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 2. 创建应用上下文(AnnotationConfigApplicationContext或Web类型)
ConfigurableApplicationContext context = createApplicationContext();
// 3. 准备环境配置
ConfigurableEnvironment environment = prepareEnvironment();
// 4. 执行refresh方法(核心!!!)
refreshContext(context);
// 5. 触发启动完成事件
callRunners(context.getBean(ApplicationRunner.class));
return context;
}
二、refresh方法全流程解析
AbstractApplicationContext#refresh()
是Spring容器初始化的核心方法,共包含12个关键步骤:
2.1 源码结构概览
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 步骤1:准备上下文环境
prepareRefresh();
// 步骤2:创建并配置BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 步骤3:BeanFactory预处理
prepareBeanFactory(beanFactory);
try {
// 步骤4:后置处理BeanFactory(空方法,供子类扩展)
postProcessBeanFactory(beanFactory);
// 步骤5:调用BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 步骤6:注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 步骤7:初始化消息资源
initMessageSource();
// 步骤8:初始化事件广播器
initApplicationEventMulticaster();
// 步骤9:子类扩展刷新逻辑
onRefresh();
// 步骤10:注册监听器
registerListeners();
// 步骤11:完成Bean初始化
finishBeanFactoryInitialization(beanFactory);
// 步骤12:完成刷新,发布事件
finishRefresh();
}
// ... 异常处理
}
}
2.2 关键步骤详解
2.2.1 prepareRefresh()
- 设置容器启动时间戳
startupDate
- 初始化早期事件集合
earlyApplicationEvents
- 校验必需属性(如
Environment
中的占位符)
2.2.2 obtainFreshBeanFactory()
- 创建DefaultListableBeanFactory:Spring的核心Bean工厂实现
- 加载Bean定义(XML或注解方式)
- 设置序列化ID用于反序列化
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
2.2.3 invokeBeanFactoryPostProcessors()
BeanFactoryPostProcessor执行顺序:
- BeanDefinitionRegistryPostProcessor(优先级最高)
- 实现类示例:
ConfigurationClassPostProcessor
(处理@Configuration
类)
- 实现类示例:
- BeanFactoryPostProcessor
- 按
PriorityOrdered
>Ordered
> 无顺序执行
- 按
源码示例:
// 获取并排序BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
2.2.4 registerBeanPostProcessors()
注册所有BeanPostProcessor
,执行顺序同样遵循PriorityOrdered
> Ordered
> 无顺序。
重要子类处理器:
- InstantiationAwareBeanPostProcessor:在Bean实例化前后介入(如AOP代理)
- CommonAnnotationBeanPostProcessor:处理
@PostConstruct
等JSR-250注解
2.2.5 finishBeanFactoryInitialization()
- 实例化所有非懒加载的单例Bean:通过
beanFactory.preInstantiateSingletons()
触发 - 解决循环依赖:三级缓存机制(singletonFactories、earlySingletonObjects、singletonObjects)
三、核心处理器深度解析
3.1 BeanFactoryPostProcessor
作用:在Bean定义加载完成后、实例化前修改BeanDefinition。
典型应用:
PropertySourcesPlaceholderConfigurer
:解析${}
占位符ConfigurationClassPostProcessor
:解析@Configuration
类中的@Bean
方法
3.2 BeanPostProcessor
执行时机:
- postProcessBeforeInitialization:在
@PostConstruct
和InitializingBean
之前执行 - postProcessAfterInitialization:在Bean初始化完成后执行(如生成代理对象)
示例代码:
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 前置处理逻辑
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 后置处理逻辑(如AOP代理)
return wrapIfNecessary(bean, beanName);
}
}
四、事件机制与监听器
4.1 事件发布流程
- ApplicationEventPublisher:通过
publishEvent()
发布事件 - ApplicationEventMulticaster:将事件广播给所有匹配的监听器
4.2 内置事件类型
- ContextRefreshedEvent:容器刷新完成时触发
- ContextClosedEvent:容器关闭时触发
- RequestHandledEvent:HTTP请求处理完成后触发
监听器注册示例:
@Component
public class RefreshListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("容器初始化完成!");
}
}
五、总结与最佳实践
5.1 启动优化建议
- 减少组件扫描范围:通过
@ComponentScan
的basePackages
属性限定路径 - 排除不必要的自动配置:使用
exclude
属性禁用特定自动配置类
5.2 扩展点应用场景
- BeanFactoryPostProcessor:动态注册Bean或修改配置
- BeanPostProcessor:实现AOP、属性校验等横切关注点
- ApplicationListener:监听容器生命周期事件,执行初始化逻辑
通过深入理解refresh方法的每个步骤及处理器的作用,开发者能够更好地定制Spring容器的行为,优化应用启动性能,并实现复杂的业务需求。