深入解析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的工作原理,在实际开发中更加得心应手。

相关推荐
cainiao0806052 分钟前
Java 大视界——Java大数据在智能安防视频监控中的异常事件快速响应与处理机制
java
爬菜12 分钟前
java事件处理机制
java
王中阳Go22 分钟前
2025Java面试八股②(含121道面试题和答案)
java·后端·面试
neoooo22 分钟前
🎯 深入理解:JOIN 中 ON vs WHERE 条件差异
java·后端·mysql
boy快快长大34 分钟前
【线程与线程池】线程数设置(四)
java·开发语言
小鸡脚来咯38 分钟前
ThreadLocal实现原理
java·开发语言·算法
程序员阿斌哥1 小时前
记录一次jenkins slave因为本地安装多个java版本导致的问题
java·jenkins
张哈大1 小时前
【 java 虚拟机知识 第二篇 】
java·开发语言·jvm·笔记
知其然亦知其所以然1 小时前
只会写 Mapper 就想进大厂?MyBatis 原理你真懂了吗?
java·后端·面试
九月十九1 小时前
java操作word里的表格
java·word