深入解析Spring启动流程:从源码角度一步步揭秘Spring的魔法

📚 前言

Spring框架作为Java生态中最流行的框架之一,其启动流程一直是Java开发者需要深入理解的重要知识点。本文将从源码角度深入分析Spring的完整启动流程,帮助你理解Spring容器是如何初始化并管理Bean的。通过本文,你将了解Spring启动过程中的每一个关键步骤,掌握Spring容器的核心工作原理。

🔍 Spring启动流程概述

Spring的启动流程主要分为两个阶段:容器初始化和容器刷新。在这两个阶段中,Spring完成了从配置解析到Bean实例化、初始化的全过程。

🏗️ 一、容器初始化阶段

容器初始化阶段主要完成以下工作:

1.创建Spring容器(ApplicationContext)

2.准备必要的工具类和组件

3.加载和解析配置

1.1 创建ApplicationContext

以AnnotationConfigApplicationContext为例(基于Java配置类的方式),其构造过程如下:

java 复制代码
// 创建AnnotationConfigApplicationContext对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

这行代码背后发生了什么?让我们看看源码:

java 复制代码
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    // 调用无参构造函数
    this();
    // 注册配置类
    register(componentClasses);
    // 刷新容器
    refresh();
}

public AnnotationConfigApplicationContext() {
    // 创建一个读取注解的Bean定义读取器
    this.reader = new AnnotatedBeanDefinitionReader(this);
    // 创建一个扫描器,用于扫描包或类,转换为BeanDefinition
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

💡 关键点:在创建AnnotationConfigApplicationContext时,Spring首先会创建一个Bean工厂(DefaultListableBeanFactory),然后创建注解Bean定义读取器和类路径扫描器,为后续的Bean扫描和注册做准备。

1.2 创建AnnotatedBeanDefinitionReader

AnnotatedBeanDefinitionReader用于读取注解配置,并将其转换为BeanDefinition。在创建过程中,会注册一些基础的后置处理器:

java 复制代码
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    // 注册注解配置处理器
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

在registerAnnotationConfigProcessors方法中,会注册以下关键组件:

java 复制代码
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
        BeanDefinitionRegistry registry, @Nullable Object source) {
    
    // 注册ConfigurationClassPostProcessor,用于处理@Configuration、@Import等注解
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 注册AutowiredAnnotationBeanPostProcessor,用于处理@Autowired注解
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 注册CommonAnnotationBeanPostProcessor,用于处理@Resource等注解
    if (!registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    
    // 其他处理器注册...
    
    return beanDefs;
}

🔍 注意:这些后置处理器是Spring框架的核心组件,它们负责处理各种注解,实现依赖注入、AOP等功能。

1.3 创建ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner用于扫描指定包路径下的类,并将符合条件的类转换为BeanDefinition:

java 复制代码
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
    this(registry, true);
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
    this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
        Environment environment) {
    this(registry, useDefaultFilters, environment,
            (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}

在构造过程中,会设置默认的过滤器,用于筛选带有@Component、@Repository、@Service和@Controller注解的类。

1.4 注册配置类

在创建完AnnotationConfigApplicationContext后,会调用register方法注册配置类:

java 复制代码
public void register(Class<?>... componentClasses) {
    for (Class<?> componentClass : componentClasses) {
        registerBean(componentClass);
    }
}

public void registerBean(Class<?> beanClass) {
    doRegisterBean(beanClass, null, null, null);
}

<T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
        @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
        @Nullable BeanDefinitionCustomizer... customizers) {
    
    // 创建AnnotatedGenericBeanDefinition,包含了类的各种元信息
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    
    // 判断是否需要跳过注册
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }
    
    // 设置Bean的作用域等信息
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    
    // 处理通用注解
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    
    // 处理限定符注解
    if (qualifiers != null) {
        for (Class<? extends Annotation> qualifier : qualifiers) {
            if (Primary.class == qualifier) {
                abd.setPrimary(true);
            }
            else if (Lazy.class == qualifier) {
                abd.setLazyInit(true);
            }
            else {
                abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }
    
    // 应用自定义设置
    if (customizers != null) {
        for (BeanDefinitionCustomizer customizer : customizers) {
            customizer.customize(abd);
        }
    }
    
    // 创建BeanDefinitionHolder并注册
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

🌟 重要:这一步将配置类本身注册为一个Bean,这样Spring才能对其进行处理,解析其中的配置信息。

🔄 二、容器刷新阶段

容器刷新是Spring启动过程中最核心的部分,通过调用refresh()方法完成。这个方法定义在AbstractApplicationContext类中,包含了12个关键步骤:

java 复制代码
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1. 准备刷新上下文环境
        prepareRefresh();

        // 2. 获取BeanFactory,对于AnnotationConfigApplicationContext,直接返回已创建的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. 初始化特定上下文子类中的其他特殊Bean
            onRefresh();

            // 10. 注册监听器
            registerListeners();

            // 11. 初始化所有非懒加载的单例Bean
            finishBeanFactoryInitialization(beanFactory);

            // 12. 完成刷新,发布相应的事件
            finishRefresh();
        }
        catch (BeansException ex) {
            // 销毁已创建的Bean
            destroyBeans();

            // 取消刷新
            cancelRefresh(ex);

            throw ex;
        }
        finally {
            // 重置通用缓存
            resetCommonCaches();
        }
    }
}

下面我们详细分析这12个步骤:

2.1 prepareRefresh - 准备刷新

java 复制代码
protected void prepareRefresh() {
    // 记录启动时间
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    // 初始化属性源
    initPropertySources();

    // 验证必要的属性
    getEnvironment().validateRequiredProperties();

    // 存储早期的应用事件
    if (this.earlyApplicationEvents == null) {
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }
}

这一步主要是做一些准备工作,包括记录启动时间、初始化属性源、验证必要的属性等。

2.2 obtainFreshBeanFactory - 获取BeanFactory

java 复制代码
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

对于AnnotationConfigApplicationContext,这一步直接返回已创建的DefaultListableBeanFactory。

2.3 prepareBeanFactory - 准备BeanFactory

java 复制代码
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    
    // 设置表达式解析器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    
    // 添加属性编辑器注册器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 添加ApplicationContextAwareProcessor,处理各种Aware接口
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
    // 设置忽略的依赖接口
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // 注册可解析的依赖
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // 添加ApplicationListenerDetector
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // 添加LoadTimeWeaverAwareProcessor
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // Set a temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // 注册默认环境Bean
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

这一步为BeanFactory设置了各种属性和组件,包括类加载器、表达式解析器、属性编辑器、后置处理器等,还注册了一些默认的单例Bean。

2.4 postProcessBeanFactory - 允许子类修改BeanFactory

java 复制代码
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 空实现,留给子类扩展
}

这是一个模板方法,允许子类在标准初始化后修改BeanFactory。

2.5 invokeBeanFactoryPostProcessors - 执行BeanFactoryPostProcessor

java 复制代码
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // 如果LoadTimeWeaver可用,则添加LoadTimeWeaverAwareProcessor
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

这一步执行所有的BeanFactoryPostProcessor,包括我们在1.2节中注册的ConfigurationClassPostProcessorConfigurationClassPostProcessor会处理@Configuration@ComponentScan@Import等注解,完成Bean的扫描和注册。

🔥 核心步骤:这是Spring启动过程中最核心的步骤之一,完成了Bean的扫描和注册。

2.6 registerBeanPostProcessors - 注册BeanPostProcessor

java 复制代码
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

这一步注册所有的BeanPostProcessor,包括我们在1.2节中注册的AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor。这些后置处理器会在Bean的初始化前后执行,实现依赖注入等功能。

2.7 initMessageSource - 初始化消息源

java 复制代码
protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        // 设置父消息源
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
            if (hms.getParentMessageSource() == null) {
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
    }
    else {
        // 创建默认的消息源
        DelegatingMessageSource dms = new DelegatingMessageSource();
        dms.setParentMessageSource(getInternalParentMessageSource());
        this.messageSource = dms;
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
    }
}

这一步初始化消息源,用于国际化。

2.8 initApplicationEventMulticaster - 初始化事件广播器

java 复制代码
protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    }
    else {
        // 创建默认的事件广播器
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    }
}

这一步初始化事件广播器,用于发布应用事件。

2.9 onRefresh - 初始化特定上下文子类中的其他特殊Bean

java 复制代码
protected void onRefresh() {
    // 空实现,留给子类扩展
}

这是一个模板方法,允许子类在容器刷新时初始化其他特殊Bean。

2.10 registerListeners - 注册监听器

java 复制代码
protected void registerListeners() {
    // 注册静态指定的监听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 注册监听器Bean
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // 发布早期的应用事件
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

这一步注册所有的事件监听器,并发布早期的应用事件。

2.11 finishBeanFactoryInitialization - 初始化所有非懒加载的单例Bean

java 复制代码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化转换服务
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // 注册默认的嵌入值解析器
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // 初始化LoadTimeWeaverAware Bean
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // 停止使用临时类加载器
    beanFactory.setTempClassLoader(null);

    // 冻结配置
    beanFactory.freezeConfiguration();

    // 初始化所有非懒加载的单例Bean
    beanFactory.preInstantiateSingletons();
}

这一步初始化所有非懒加载的单例Bean,是Spring启动过程中最核心的步骤之一。

💡 关键点:preInstantiateSingletons方法会遍历所有的Bean定义,创建所有非懒加载的单例Bean。

2.12 finishRefresh - 完成刷新

java 复制代码
protected void finishRefresh() {
    // 清除资源缓存
    clearResourceCaches();

    // 初始化生命周期处理器
    initLifecycleProcessor();

    // 调用生命周期处理器的onRefresh方法
    getLifecycleProcessor().onRefresh();

    // 发布ContextRefreshedEvent事件
    publishEvent(new ContextRefreshedEvent(this));

    // 注册MBean
    LiveBeansView.registerApplicationContext(this);
}

这一步完成容器的刷新,发布ContextRefreshedEvent事件,表示容器已经刷新完成。

🌱 三、Bean的生命周期

在Spring容器启动过程中,Bean的生命周期是一个重要的概念。下面是Bean的完整生命周期流程图:

Bean的生命周期主要包括以下步骤:

1.实例化Bean (Instantiate)

2.设置属性 (Populate Properties)

3.如果实现了BeanNameAware接口,调用setBeanName()

4.如果实现了BeanFactoryAware接口,调用setBeanFactory()

5.如果实现了ApplicationContextAware接口,调用setApplicationContext()

6.调用BeanPostProcessor的前置处理方法postProcessBeforeInitialization()

7.如果实现了InitializingBean接口,调用afterPropertiesSet()

8.调用自定义的init-method方法

9.调用BeanPostProcessor的后置处理方法postProcessAfterInitialization()

10.Bean可以使用了 (Bean Ready to Use)

11.如果实现了DisposableBean接口,调用destroy()

12.调用自定义的destroy-method方法

这些步骤在Spring容器的finishBeanFactoryInitialization方法中完成,具体实现在DefaultListableBeanFactory的preInstantiateSingletons方法和AbstractAutowireCapableBeanFactory的createBean方法中。

📝 总结

通过本文,我们深入分析了Spring的完整启动流程,包括容器初始化和容器刷新两个阶段。在这个过程中,Spring完成了从配置解析到Bean实例化、初始化的全过程。理解这个过程对于深入使用Spring框架、解决Spring相关问题非常有帮助。

Spring的启动流程虽然复杂,但是设计得非常优雅,通过各种设计模式(如模板方法、观察者、工厂等)实现了高度的可扩展性和灵活性。希望本文能帮助你更好地理解Spring的工作原理,在实际开发中更加得心应手。

相关推荐
StockTV1 分钟前
印度股票实时数据 NSE和BSE的实时行情、K 线及指数数据
java·开发语言·spring boot·python
User_芊芊君子4 分钟前
【OpenAI 把 AI 玩明白了】:自主推理 + 动态知识图谱,这 4 个技术突破要颠覆行业
java·人工智能·知识图谱
c++之路37 分钟前
C++20概述
java·开发语言·c++20
Championship.23.2441 分钟前
Linux Top 命令族深度解析与实战指南
java·linux·服务器·top·linux调试
橘子海全栈攻城狮1 小时前
【最新源码】养老院系统管理A013
java·spring boot·后端·web安全·微信小程序
逻辑驱动的ken1 小时前
Java高频面试考点18
java·开发语言·数据库·算法·面试·职场和发展·哈希算法
冷雨夜中漫步2 小时前
Claude Code源码分析——Claude Code Agent Loop 详细设计文档
java·开发语言·人工智能·ai
直奔標竿2 小时前
Java开发者AI转型第二十六课!Spring AI 个人知识库实战(五)——联网搜索增强实战
java·开发语言·人工智能·spring boot·后端·spring
one_love_zfl2 小时前
java面试-微服务组件篇
java·微服务·面试
一只大袋鼠2 小时前
Java进阶:CGLIB动态代理解析
java·开发语言