Spring源码深度解析:从启动到refresh全流程剖析

一、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()方法触发容器初始化流程:

  1. 创建SpringApplication实例:加载META-INF/spring.factories中的ApplicationContextInitializerApplicationListener
  2. 执行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执行顺序

  1. BeanDefinitionRegistryPostProcessor(优先级最高)
    • 实现类示例:ConfigurationClassPostProcessor(处理@Configuration类)
  2. 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

执行时机

  1. postProcessBeforeInitialization:在@PostConstructInitializingBean之前执行
  2. 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 事件发布流程

  1. ApplicationEventPublisher:通过publishEvent()发布事件
  2. 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 启动优化建议

  • 减少组件扫描范围:通过@ComponentScanbasePackages属性限定路径
  • 排除不必要的自动配置:使用exclude属性禁用特定自动配置类

5.2 扩展点应用场景

  • BeanFactoryPostProcessor:动态注册Bean或修改配置
  • BeanPostProcessor:实现AOP、属性校验等横切关注点
  • ApplicationListener:监听容器生命周期事件,执行初始化逻辑

通过深入理解refresh方法的每个步骤及处理器的作用,开发者能够更好地定制Spring容器的行为,优化应用启动性能,并实现复杂的业务需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值