【Spring源码分析】refresh方法

【Spring源码分析】refresh方法

refresh 是 AbstractApplicationContext 中的一个方法,负责初始化 ApplicationContext 容器,内部主要包含 12 个关键方法:

在这里插入图片描述

// org.springframework.context.support.AbstractApplicationContext

@Override
public void refresh() throws BeansException, IllegalStateException {
    // 来个锁,不然 refresh() 还没结束,又来个启动或销毁容器的操作,那就乱套了
    synchronized (this.startupShutdownMonitor) {

        // 1. 准备工作(初始化Environment对象、earlyApplicationListeners、earlyApplicationEvents)
        prepareRefresh();

        // 2. 创建 BeanFactory(DefaultListableBeanFactory),解析并注册Bean(生成 BeanDefination 并注册到 BeanFactory 中的 beanDefinitionMap)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 3. 填充BeanFactory的一些属性
        prepareBeanFactory(beanFactory);

        // 到这里,BeanFactory已经创建完成,所有的 Bean 都加载、注册完成了,但是都还没有初始化。
        try {
            // 4. 提供给子类的扩展点(在所有的BeanDefination加载完成之后,bean实例化之前执行)
            // 比如在BeanFactory加载完所有的bean后,想修改其中某个bean的定义,或者对beanFactory做一些其他的配置
            postProcessBeanFactory(beanFactory);

            // 5. 调用已经注册的 BeanFactoryPostProcessor 接口各实现类的 postProcessBeanFactory 方法
            invokeBeanFactoryPostProcessors(beanFactory);

            // 6. 按顺序注册 BeanPostProcessor(就是添加到 BeanFactory 的 beanPostProcessors 列表中)
            // 例如:
            // AutowiredAnnotationBeanPostProcessor:解析 @Autowired,@Value 注解
            // CommonAnnotationBeanPostProcessor:解析 @Resource,@PostConstruct,@PreDestroy
            registerBeanPostProcessors(beanFactory);

            // 7. 初始化 message source,实现国际化功能(初始化 ApplicationContext 的 messageSource)
            initMessageSource();

            // 8. 初始化 event multicaster,用于发布事件(初始化 ApplicationContext 的 applicationEventMulticaster)
            initApplicationEventMulticaster();

            // 9. 提供给子类的扩展点(可以在这里初始化一些特殊的 Bean)
            onRefresh();

            // 10. 注册事件监听器,发布 earlyApplicationEvents
            registerListeners();

            // 11. 初始化一些转换器;实例化所有的非懒加载的单例bean
            finishBeanFactoryInitialization(beanFactory);

            // 12. 调用 LifecycleProcessor 的 onRefresh方法;发布 ContextRefreshedEvent
            finishRefresh();
        }

        catch (BeansException ex) {
            // logger...

            // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
            destroyBeans();

            // active = false
            cancelRefresh(ex);

            // 抛出异常
            throw ex;
        }

        finally {
            // 清空产生的缓存数据
            resetCommonCaches();
        }
    }
}

01、prepareRefresh

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected void prepareRefresh() {  
    // Switch to active.
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    // logger...

    // 初始化一些属性资源
    initPropertySources();

    // 获取Environment对象(不存在则创建);验证required的属性是否都已经放入环境中
    getEnvironment().validateRequiredProperties();

    // Store pre-refresh ApplicationListeners...
    if (this.earlyApplicationListeners == null) {
        // 将 applicationListeners 赋值给 earlyApplicationListeners
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    } else {
        // 将 applicationListeners 重置为 earlyApplicationListeners
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // 初始化集合,用于存放ApplicationEvents,一旦multicaster可用就发布事件(在 registerListeners 方法中发布)
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

2、小结

创建 Bean 容器前的准备工作。

  • 切换到活动状态:记录启动时间、关闭状态=false、活跃状态=true
  • 初始化一些属性资源
  • 获取Environment对象(不存在则创建),验证 required =true 的属性是否存在。
  • 准备早期的 ApplicationListener
  • 初始化 ApplicationEvent(空集合),一旦multicaster可用就发布事件(在 registerListeners 方法中发布)

在这里插入图片描述

02、obtainFreshBeanFactory

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 刷新 BeanFactory
    refreshBeanFactory();
    // 返回 BeanFactory(DefaultListableBeanFactory)
    return getBeanFactory();
}
// org.springframework.context.support.AbstractRefreshableApplicationContext

@Override
protected final void refreshBeanFactory() throws BeansException {
    // 当前 ApplicationContext 是否有 BeanFactory
    if (hasBeanFactory()) {
        // 销毁bean
        destroyBeans();
        // 关闭BeanFactory
        closeBeanFactory();
    }

    try {
        // 创建 DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        // 指定序列化id(spring.application.name)
        beanFactory.setSerializationId(getId());
        // 设置 BeanFactory 的两个配置属性:「是否允许Bean覆盖」、「是否允许循环引用」
        customizeBeanFactory(beanFactory);
        // 加载 BeanDefinitions
        loadBeanDefinitions(beanFactory);
        this.beanFactory = beanFactory;
    } catch (IOException ex) {
        throw new ApplicationContextException(...., ex);
    }
}

SpringBoot 走的是 GenericApplicationContext 的实现

// org.springframework.context.support.GenericApplicationContext

@Override
protected final void refreshBeanFactory() throws IllegalStateException {
    // 更新this.refreshed字段为true, 表示已刷新
    if (!this.refreshed.compareAndSet(false, true)) {
        throw new IllegalStateException(
            "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
    }
    // 指定序列化id(spring.application.name)
    this.beanFactory.setSerializationId(getId());
}

2、DefaultListableBeanFactory

为什么 createBeanFactory 选择 DefaultListableBeanFactory 呢?

分析一下继承图:

在这里插入图片描述

可以看到:

  • ConfigurableListableBeanFactory 只有一个实现类 DefaultListableBeanFactory
  • DefaultListableBeanFactory 还通过实现右边的 AbstractAutowireCapableBeanFactory 通吃了右路

因此,DefaultListableBeanFactory 基本上是最牛的 BeanFactory 了,这也是为什么会选择实例化这个类的原因。

/**
 * 如何在运行时获取 `DefaultListableBeanFactory` 实例?
 */
public class GetDefaultListableBeanFactory {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 1. getAutowireCapableBeanFactory 获取 AutowireCapableBeanFactory
        // 2. AutowireCapableBeanFactory 向下转型得到 DefaultListableBeanFactory
        DefaultListableBeanFactory autowireCapableBeanFactory = 
            (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
    }
}

3、小结

创建 Bean 容器(DefaultListableBeanFactory),解析并注册 Bean(生成 BeanDefination 注册到 BeanFactory 中)

  • 关闭旧的 BeanFactory(如果有),创建新的 BeanFactory(DefaultListableBeanFactory)
  • 设置 SerializationId(允许BeanFactory的序列化)
  • 设置 「是否允许 Bean 覆盖」 和 「是否允许循环引用」
  • 加载 BeanDefinitions,存入 BeanFactory 中的 beanDefinitionMap 集合

在这里插入图片描述

03、prepareBeanFactory

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置beanFactory的类加载器:存在则直接设置/不存在则新建一个默认类加载器
    beanFactory.setBeanClassLoader(getClassLoader());

    // 设置SpEL表达式解析器(Bean初始化完成后填充属性时会用到)
    beanFactory.setBeanExpressionResolver(
        new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

    // 设置属性注册解析器 PropertyEditorRegistrar
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 添加后置处理器 ApplicationContextAwareProcessor
    // 实现了 Aware 接口的 beans 在初始化的时候,这个 processor 负责回调
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

    // 如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们,Spring 会通过其他方式来处理这些依赖。
    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 interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // 添加后置处理器 ApplicationListenerDetector
    // 检测并注册实现了 ApplicationListener 接口的 Bean 作为事件监听器。
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // 是否存在名为 loadTimeWeaver 的Bean(在类加载时织入AspectJ,添加额外的逻辑或增强类的功能)
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        // 添加后置处理器 LoadTimeWeaverAwareProcessor
        // 负责将 loadTimeWeaver 注入到 Spring 托管的对象中。
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // 为类型匹配设置一个临时的ClassLoader
        beanFactory.setTempClassLoader(
            new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // 注册一些组件bean:environment、systemProperties、systemEnvironment
    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());
    }
}

2、小结

创建了BeanFactory,但它当中很多属性都是为null,所以这个方法主要是对 BeanFactory 属性进行填充。

  • 设置 BeanFactory 的类加载器。
  • 设置 BeanExpressionResolver,用于解析SpEL表达式。
  • 添加 PropertyEditorRegistrar,应用 ApplicationContext 提供的 Environment 完成 ${} 解析。
  • 注册 ResolvableDependency,注册 BeanFactory 以及 ApplicationContext,让它们也能用于依赖注入。
  • 此处会添加两个 BeanPostProcessor:
    • ApplicationContextAwareProcessor 用来解析 Aware 接口
    • ApplicationListenerDetector 用来检测容器中 ApplicationListener 类型的 bean
  • 注册一些组件bean:environment、systemProperties、systemEnvironment

在这里插入图片描述

04、postProcessBeanFactory

这一步是空实现,留给子类扩展。

// org.springframework.context.support.AbstractApplicationContext

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

一般 Web 环境的 ApplicationContext 都要利用它注册新的 Scope,完善 Web 下的 BeanFactory

// org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 添加后置处理器 WebApplicationContextServletContextAwareProcessor
    beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
    // 忽略自动装配接口
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    // 注册了web的scope作用域,这里有request、session、application
    registerWebApplicationScopes();
}

05、invokeBeanFactoryPostProcessors

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 委托 PostProcessorRegistrationDelegate 循环执行每个 BeanFactoryPostProcessor
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // 如果在此期间发现LoadTimeWeaver,则准备织入
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors 方法中,重点关注以下内容

// org.springframework.context.support.PostProcessorRegistrationDelegate

public static void invokeBeanFactoryPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // ...
    
	// DefaultListableBeanFactory -> BeanDefinitionRegistry
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    
    List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

    // 调用 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

    // 调用 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
    invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    
    // ...
}

private static void invokeBeanDefinitionRegistryPostProcessors(
    Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}

private static void invokeBeanFactoryPostProcessors(
    Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanFactory(beanFactory);
    }
}

2、BeanFactoryPostProcessor

@FunctionalInterface
public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
  • 作用:在容器已经加载了 BeanDefinition 并且实例化了部分 Bean 之后,对已经注册的 Bean 进行进一步的修改、添加或删除。
  • 时机:在 Spring 容器加载了 Bean 定义并实例化了部分 Bean 之后,但在其余 Bean 实例化之前调用。
  • 扩展:开发者可以实现 BeanFactoryPostProcessor 接口来自定义 BeanFactory 的后置处理行为。

3、BeanDefinitionRegistryPostProcessor

// 继承于 BeanFactoryPostProcessor
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
  • 作用:在 BeanDefinition 被加载到容器之后、实例化之前,对 BeanDefinition 进行修改、添加或删除。
  • 时机:在 Spring 容器加载 Bean 定义后,但在实例化 Bean 之前调用。
  • 扩展:开发者可以实现 BeanDefinitionRegistryPostProcessor 接口来自定义 BeanDefinition 的注册行为。

4、小结

调用 BeanFactoryPostProcessor 接口各实现类的 postProcessBeanFactory 方法

BeanFactoryPostProcessor 充当 beanFactory 的扩展点,可以用来补充或修改 BeanDefinition,常见的有:

  • ConfigurationClassPostProcessor:解析 @Configuration、@Bean、@Import、@PropertySource 等
  • MapperScannerConfigurer:补充 Mapper 接口对应的 BeanDefinition

在这里插入图片描述

06、registerBeanPostProcessors

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 委托 PostProcessorRegistrationDelegate 注册 BeanPostProcessor
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
// org.springframework.context.support.PostProcessorRegistrationDelegate

public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // 获取所有 BeanPostProcessor 的 beanName
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // BeanPostProcessor的数量
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;

    // 添加后置处理器 BeanPostProcessorChecker(主要用于记录信息)
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // 将BeanPostProcessors分为实现了PriorityOrdered接口,Ordered接口、普通的类型
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        // 添加实现了 PriorityOrdered 接口的 BeanPostProcessor
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        // 添加实现了 Ordered 接口的 BeanPostProcessor
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        // 添加其他无序的 BeanPostProcessor
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 首先,排序并注册实现了 PriorityOrdered 接口的 BeanPostProcessor
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // 然后,排序并注册实现了 Ordered 接口的 BeanPostProcessor
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // 然后,注册所有无序的 BeanPostProcessor
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // 最后, 排序并注册所有内部的 BeanPostProcessor
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // 重新注册 ApplicationListenerDetector(将其移动到处理器链的末端,用于接收代理等)
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

注册 BeanPostProcessor,其实就是添加到 IoC容器的 beanPostProcessors 列表中

// org.springframework.context.support.PostProcessorRegistrationDelegate

// 注册 BeanPostProcessor
private static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

    for (BeanPostProcessor postProcessor : postProcessors) {
        beanFactory.addBeanPostProcessor(postProcessor);
    }
}
// org.springframework.beans.factory.support.AbstractBeanFactory

private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // Remove from old position, if any
    this.beanPostProcessors.remove(beanPostProcessor);
    // Track whether it is instantiation/destruction aware
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
        this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
        this.hasDestructionAwareBeanPostProcessors = true;
    }
    // Add to end of list
    this.beanPostProcessors.add(beanPostProcessor);
}

2、BeanPostProcessor

public interface BeanPostProcessor {

    // Bean 初始化之前调用
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    // Bean 初始化之后调用
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
  • 作用:对容器中已经实例化的 Bean 进行后置处理,主要是在 Bean 的初始化前后进行一些定制化的处理操作。
  • 时机:在 Bean 的生命周期的初始化阶段。
  • 扩展:开发者可以实现 BeanPostProcessor 接口来自定义 Bean 的初始化前后处理行为。

3、小结

排序并注册 BeanPostProcessor(添加至 BeanFactory 的 beanPostProcessors 集合中),只注册,不调用,等初始化的时候再调用。

  • 首先,排序并注册实现了 PriorityOrdered 接口的 BeanPostProcessor。
  • 然后,排序并注册实现了 Ordered 接口的 BeanPostProcessor。
  • 然后,注册所有无序的 BeanPostProcessor。
  • 最后, 排序并注册所有内部的 BeanPostProcessor(内部的BeanPostProcessor在处理器链的末尾)
  • 重新注册 ApplicationListenerDetector(将其移动到处理器链的末端,用于接收代理等)

在这里插入图片描述

07、initMessageSource

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    
    // beanFactory 包含 messageSource 这个bean
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        // 设置父MessageSource
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
            if (hms.getParentMessageSource() == null) {
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
        if (logger.isTraceEnabled()) {
            logger.trace("Using MessageSource [" + this.messageSource + "]");
        }
    }
    
    // beanFactory 不包含 messageSource 这个bean
    else {
        // 默认使用 DelegatingMessageSource
        DelegatingMessageSource dms = new DelegatingMessageSource();
        // 设置父MessageSource
        dms.setParentMessageSource(getInternalParentMessageSource());
        this.messageSource = dms;
        // 注册 messageSource 这个bean(使用 DelegatingMessageSource)
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
        }
    }
}

2、MessageSource

MessageSource 是 Spring 框架中用于提供国际化消息的接口。

  • 它允许开发者在应用程序中使用统一的方式来获取消息,从而支持应用程序的国际化和本地化。
public interface MessageSource {
    @Nullable
    String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
    String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
    String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}

3、DelegatingMessageSource

在 Spring 中,通常会使用 DelegatingMessageSource 来作为应用程序的主要消息源管理器

  • 它可以通过配置多个 MessageSource 实现类来实现更加灵活的国际化消息管理。

获取国际化消息时,DelegatingMessageSource 会根据配置的优先级顺序逐个查找消息源,直到找到对应的消息为止。

import org.springframework.context.support.DelegatingMessageSource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.context.support.ResourceBundleMessageSource;

public class Main {
    
    public static void main(String[] args) {
        DelegatingMessageSource messageSource = new DelegatingMessageSource();
        
        // 添加多个消息源,按照优先级顺序进行查找
        ReloadableResourceBundleMessageSource resourceBundleMessageSource1 = new ReloadableResourceBundleMessageSource();
        resourceBundleMessageSource1.setBasename("messages1");
        
        ReloadableResourceBundleMessageSource resourceBundleMessageSource2 = new ReloadableResourceBundleMessageSource();
        resourceBundleMessageSource2.setBasename("messages2");
        
        ResourceBundleMessageSource defaultSource = new ResourceBundleMessageSource();
        defaultSource.setBasename("messages");
        
        messageSource.setParentMessageSource(defaultSource);
        messageSource.setMessageSources(new MessageSource[]{resourceBundleMessageSource1, resourceBundleMessageSource2});
        
        // 获取国际化消息
        String message = messageSource.getMessage("hello.world", null, "Default Message", null);
        System.out.println(message);
    }
}

4、小结

初始化MessageSource组件,为 ApplicationContext 添加 messageSource 成员,实现国际化功能

  • 去 BeanFactory 内找名为 messageSource 的 bean,如果没有,默认使用 DelegatingMessageSource 实现
  • 设置父MessageSource

在这里插入图片描述

08、initApplicationEventMulticaster

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    
    // 判断BeanFactory是否已经存在事件广播器(applicationEventMulticaster)
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        // 如果已经存在,则使用已存在的事件广播器
        this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isTraceEnabled()) {
            logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        // 如果不存在,默认使用 SimpleApplicationEventMulticaster
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        // 注册 applicationEventMulticaster 这个bean(使用 SimpleApplicationEventMulticaster)
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                         "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
        }
    }
}

2、ApplicationEventMulticaster

ApplicationEventMulticaster 是 Spring 框架中用于管理和广播应用程序事件的核心接口。

  • 它允许应用程序中的组件向其他组件发送事件通知,并且支持同步和异步两种方式进行事件广播。
public interface ApplicationEventMulticaster {

    // 添加指定 ApplicationListener
	void addApplicationListener(ApplicationListener<?> listener);
	void addApplicationListenerBean(String listenerBeanName);

    // 移除指定 ApplicationListener
	void removeApplicationListener(ApplicationListener<?> listener);
	void removeApplicationListenerBean(String listenerBeanName);

    // 移除所有 ApplicationListener
	void removeAllListeners();

    // 发布事件
	void multicastEvent(ApplicationEvent event);
	void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
}

3、SimpleApplicationEventMulticaster

SimpleApplicationEventMulticaster 是默认的 ApplicationEventMulticaster 实现,用于同步广播事件。

// org.springframework.context.event.SimpleApplicationEventMulticaster

@Nullable
private Executor taskExecutor;

@Nullable
private ErrorHandler errorHandler;

@Override
public void multicastEvent(ApplicationEvent event) {
    // 广播事件
    multicastEvent(event, resolveDefaultEventType(event));
}

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    // 获取线程池
    Executor executor = getTaskExecutor();
    for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        // 线程池异步执行
        if (executor != null) {
            executor.execute(() -> invokeListener(listener, event));
        }
        // 同步执行
        else {
            invokeListener(listener, event);
        }
    }
}

protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
    // 获取异常处理器
    ErrorHandler errorHandler = getErrorHandler();
    // 调用监听器(处理异常)
    if (errorHandler != null) {
        try {
            doInvokeListener(listener, event);
        } catch (Throwable err) {
            errorHandler.handleError(err);
        }
    } 
    // 调用监听器(不处理异常)
    else {
        doInvokeListener(listener, event);
    }
}

@SuppressWarnings({"rawtypes", "unchecked"})
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
        // 执行监听器的 onApplicationEvent 方法
        listener.onApplicationEvent(event);
    } catch (ClassCastException ex) {
        // ...
    }
}

4、小结

这一步为 ApplicationContext 添加事件广播器成员,即 applicationContextEventMulticaster,作用是发布事件给监听器

  • 去 beanFactory 找名为 applicationEventMulticaster 的 bean 作为事件广播器
  • 若没有,会创建默认的事件广播器 SimpleApplicationEventMulticaster
  • 之后就可以调用 ApplicationContext.publishEvent(事件对象) 来发布事件

在这里插入图片描述

09、onRefresh

这一步是空实现,留给子类扩展

// org.springframework.context.support.AbstractApplicationContext

protected void onRefresh() throws BeansException {
    // For subclasses: do nothing by default.
}

SpringBoot 通过 ServletWebServerApplicationContext 在这里准备了 WebServer,即内嵌 web 容器

// org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext

@Override
protected void onRefresh() {
    super.onRefresh();
    try {
        // tomcat容器就是在这里创建并启动的
        createWebServer();
    }
    catch (Throwable ex) {
        throw new ApplicationContextException("Unable to start web server", ex);
    }
}

private void createWebServer() {
    WebServer webServer = this.webServer;
    ServletContext servletContext = getServletContext();
    if (webServer == null && servletContext == null) {
        // 工厂模式 默认获取的是 TomcatServletWebServerFactory
        ServletWebServerFactory factory = getWebServerFactory();
        // 获取 TomcatWebServer,创建 Tomcat 并启动
        this.webServer = factory.getWebServer(getSelfInitializer());
        getBeanFactory().registerSingleton("webServerGracefulShutdown",
                                           new WebServerGracefulShutdownLifecycle(this.webServer));
        getBeanFactory().registerSingleton("webServerStartStop",
                                           new WebServerStartStopLifecycle(this, this.webServer));
    }
    else if (servletContext != null) {
        try {
            getSelfInitializer().onStartup(servletContext);
        }
        catch (ServletException ex) {
            throw new ApplicationContextException("Cannot initialize servlet context", ex);
        }
    }
    // 加载 Servlet 属性源
    initPropertySources();
}
// org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory

@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
    if (this.disableMBeanRegistry) {
        Registry.disableRegistry();
    }
    // 创建Tomcat
    Tomcat tomcat = new Tomcat();
    File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
    tomcat.setBaseDir(baseDir.getAbsolutePath());
    Connector connector = new Connector(this.protocol);
    connector.setThrowOnFailure(true);
    tomcat.getService().addConnector(connector);
    customizeConnector(connector);
    tomcat.setConnector(connector);
    tomcat.getHost().setAutoDeploy(false);
    configureEngine(tomcat.getEngine());
    for (Connector additionalConnector : this.additionalTomcatConnectors) {
        tomcat.getService().addConnector(additionalConnector);
    }
    prepareContext(tomcat.getHost(), initializers);
    // 启动Tomcat
    return getTomcatWebServer(tomcat);
}

protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
    return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown());
}

public TomcatWebServer(Tomcat tomcat, boolean autoStart, Shutdown shutdown) {
    Assert.notNull(tomcat, "Tomcat Server must not be null");
    this.tomcat = tomcat;
    // 自启动
    this.autoStart = autoStart;
    this.gracefulShutdown = (shutdown == Shutdown.GRACEFUL) ? new GracefulShutdown(tomcat) : null;
    // 初始化
    initialize();
}

private void initialize() throws WebServerException {
    logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
    synchronized (this.monitor) {
        try {
            // ...
            
            this.tomcat.start();	// 启动Tomcat
            
            // ...
        } 
        // ...
    }
}

10、registerListeners

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected void registerListeners() {
    // 添加静态编码指定的 ApplicationListener
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    
    // 添加注入的 ApplicationListener
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // 这里已经有了事件广播器,可以发布早期的 ApplicationEvent
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

2、ApplicationListener

ApplicationListener 是 Spring 框架中用于监听应用程序事件的接口。

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

  /**
   * 在事件发生时执行相应的逻辑。
   */
  void onApplicationEvent(E event);

}

ApplicationListener 泛型可以指定监听的 Event 类型,必须是 ApplicationEvent 或其子类

  • 如果泛型执行为 ApplicationEvent,则会监听所有的 ApplicationEvent

Spring相关的 ApplicationEvent 如下图所示:

在这里插入图片描述

自定义监听器只要实现 ApplicationListener,然后交给 Spring 容器管理即可。

3、小结

注册事件监听器(添加至 applicationEventMulticaster)。监听器需要实现 ApplicationListener 接口。

  • 添加静态编码指定的 ApplicationListener
  • 添加注入的 ApplicationListener
  • 这里已经有了事件广播器,可以发布 earlyApplicationEvents

在这里插入图片描述

11、finishBeanFactoryInitialization

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 是否存在 conversionService 这个Bean
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
        beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        // 如果存在,赋值给 beanFactory 的 conversionService
        beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // 是否存在内置的@Value解析器(例如 PropertyPlaceholderConfigurer)
    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();
}

2、小结

这一步会将 beanFactory 的成员补充完毕,并初始化所有非懒加载的单例 bean

  • conversionService 也是一套转换机制,作为对 PropertyEditor 的补充
  • embeddedValueResolvers 即内嵌值解析器,用来解析 @Value 中的 ${},借用的是 Environment 的功能
  • singletonObjects 即单例池,缓存所有单例对象

对象的创建都分三个阶段,每一阶段都有不同的 bean 后处理器参与进来,扩展功能

在这里插入图片描述

12、finishRefresh

1、源码分析

// org.springframework.context.support.AbstractApplicationContext

protected void finishRefresh() {
    // 清除上下文级别的资源缓存(例如扫描的ASM元数据)
    clearResourceCaches();

    // 初始化 lifecycleProcessor 这个bean,不存在 默认使用 DefaultLifecycleProcessor
    initLifecycleProcessor();

    // 调用 LifecycleProcessor 的 onRefresh
    getLifecycleProcessor().onRefresh();

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

    // 如果配置了 spring.liveBeansView.mbeanDomain 的系统属性,指定了MBeanServer
    // 那么会将 ApplicationContext 注册到 MBeanServer 中,
    // 可以通过 MBeanServer,对 spring容器中的bean 进行实时的查看和管理
    if (!NativeDetector.inNativeImage()) {
        LiveBeansView.registerApplicationContext(this);
    }
}
// org.springframework.context.support.AbstractApplicationContext

protected void initLifecycleProcessor() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    
    // 是否存在 lifecycleProcessor 这个bean
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        // 如果存在,则赋值给 lifecycleProcessor
        this.lifecycleProcessor =
            beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        if (logger.isTraceEnabled()) {
            logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
        }
    }
    // 如果不存在 lifecycleProcessor 这个bean
    else {
        // 默认使用 DefaultLifecycleProcessor
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        defaultProcessor.setBeanFactory(beanFactory);
        this.lifecycleProcessor = defaultProcessor;
        // 注册 lifecycleProcessor 这个bean(使用 DefaultLifecycleProcessor)
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
                         "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
        }
    }
}

2、小结

完成 refresh。主要是调用 LifecycleProcessor 的 onRefresh() 方法,并且发布事件

  • 初始化生命周期处理器 LifecycleProcessor,如果不存在默认使用 DefaultLifecycleProcessor。
  • 调用 LifecycleProcessor 的 onRefresh方法,这个方法会找出容器中实现了SmartLifecycle接口的类,并调用start方法
  • 发布ContextRefreshedEvent事件,告知对应的ApplicationListener进行相应的操作。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scj1022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值