Spring refresh 方法分析之三

  • 三哥

内容来自【自学星球】

欢迎大家来了解我的星球,和星主(也就是我)一起学习 Java ,深入 Java 体系中的所有技术。我给自己定的时间是一年,无论结果如何,必定能给星球中的各位带来点东西。

想要了解更多,欢迎访问👉:自学星球

--------------SSM系列源码文章及视频导航--------------

创作不易,望三连支持!

SSM源码解析视频

👉点我

Spring

  1. Spring 中注入 Bean 的各种骚操作做
  2. Spring 中Bean的生命周期及后置处理器使用
  3. Spring 中容器启动分析之refresh方法执行之前
  4. Spring refresh 方法分析之一
  5. Spring refresh 方法之二 invokeBeanFactoryPostProcessors 方法解析
  6. Spring refresh 方法分析之三
  7. Spring refresh 方法之四 finishBeanFactoryInitialization 分析
  8. Spring AOP源码分析一
  9. Spring AOP源码分析二
  10. Spring 事务源码分析

SpringMVC

  1. SpringMVC 启动流程源码分析
  2. SpringMVC 请求流程源码分析

MyBatis

  1. MyBatis 源码分析之 SqlSessionFactory 创建
  2. MyBatis 源码分析之 SqlSession 创建
  3. MyBatis 源码分析之 Mapper 接口代理对象生成及方法执行
  4. MyBatis 源码分析之 Select 语句执行(上)
  5. MyBatis 源码分析之 Select 语句执行(下)
  6. MyBatis 源码分析一二级缓存

---------------------【End】--------------------

一、refresh 方法之 registerBeanPostProcessors

下面我们来分析这个注册 Bean 的后置处理器方法,这里仅仅只是注册,调用阶段则是在 Bean 进行实例化的时候调用。

方法入口

registerBeanPostProcessors(beanFactory);

进入

org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 1.注册BeanPostProcessor
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

再进入会来到真正注册的方法

org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors

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

    // 找出所有实现BeanPostProcessor接口的类
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    // 获取 BeanPostProcessor 类型数量
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    // 添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    // 定义不同的变量用于区分: 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor
    // priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessor
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    // internalPostProcessors: 用于存放Spring内部的BeanPostProcessor
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    // orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanName
    List<String> orderedPostProcessorNames = new ArrayList<>();
    // nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanName
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    // 遍历postProcessorNames, 将 BeanPostProcessors 按类型区分开
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 如果ppName对应的Bean实例实现了PriorityOrdered接口, 则拿到ppName对应的Bean实例并添加到priorityOrderedPostProcessors
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                // 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
                // 则将ppName对应的Bean实例添加到internalPostProcessors
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            // 如果ppName对应的Bean实例没有实现PriorityOrdered接口, 但是实现了Ordered接口, 则将ppName添加到orderedPostProcessorNames
            orderedPostProcessorNames.add(ppName);
        }
        else {
            // 否则, 将ppName添加到nonOrderedPostProcessorNames
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    // 首先, 注册实现PriorityOrdered接口的BeanPostProcessors
    
    // 对priorityOrderedPostProcessors进行排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 注册priorityOrderedPostProcessors
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    // 接下来, 注册实现Ordered接口的BeanPostProcessors
    
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String ppName : orderedPostProcessorNames) {
        // 拿到ppName对应的BeanPostProcessor实例对象
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        // 将ppName对应的BeanPostProcessor实例对象添加到orderedPostProcessors, 准备执行注册
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            // 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
            // 则将ppName对应的Bean实例添加到internalPostProcessors
            internalPostProcessors.add(pp);
        }
    }
    // 对orderedPostProcessors进行排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    // 注册orderedPostProcessors
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    // 注册所有常规的BeanPostProcessors 
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // Finally, re-register all internal BeanPostProcessors.
    // 最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
    sortPostProcessors(internalPostProcessors, beanFactory);
    // 注册internalPostProcessors
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    // 重新注册ApplicationListenerDetector( 主要是为了移动到处理器链的末尾)
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

这个方法和 invokeBeanFactoryPostProcessors 方法的流程有点类似,先找到所有符合类型的类,然后按照不同类型进行处理,那对应上面的源码还是来总结一下干了些啥。

  1. 获取所有的实现 BeanPostProcessor 接口的类
  2. 记录获取到的 BeanPostProcessor 数量,并添加了一个用于记录信息的后置处理器
  3. 创建存放不同类型的集合,用于区分获取到的 BeanPostProcessor 类
  4. 先注册实现 PriorityOrdered接口的 BeanPostProcessor,并且判断是否还实现了 MergedBeanDefinitionPostProcessor,如果是则存放 internalPostProcessors 集合中
  5. 后注册实现了 Ordered 接口的 BeanPostProcessor,并且判断是否还实现了 MergedBeanDefinitionPostProcessor,如果是则存放 internalPostProcessors 集合中
  6. 接着注册普通的 BeanPostProcessor,并且判断是否还实现了 MergedBeanDefinitionPostProcessor,如果是则存放 internalPostProcessors 集合中
  7. 最后注册 internalPostProcessors 集合中的 BeanPostProcessor 。

以上流程很好理解,不是很难,那我们接着来看看 BeanPostProcessor 是如何注册的吧,也即 registerBeanPostProcessors 方法。

方法源码

org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors

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

    // 遍历传入的后置处理器集合,依次放入 BeanFactory 中
    for (BeanPostProcessor postProcessor : postProcessors) {
        beanFactory.addBeanPostProcessor(postProcessor);
    }
}

在进入 addBeanPostProcessor 方法

org.springframework.beans.factory.support.AbstractBeanFactory#addBeanPostProcessor

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // 如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面)
    this.beanPostProcessors.remove(beanPostProcessor);
    // 将beanPostProcessor添加到beanPostProcessors中
    this.beanPostProcessors.add(beanPostProcessor);
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
        // 如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
        // 该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessors
        this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
        // 如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
        // 该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessor
        this.hasDestructionAwareBeanPostProcessors = true;
    }
}

方法很简单,就是向 beanPostProcessors 属性添加值,并做一些额外处理。

二、refresh 方法之 initMessageSource

这个方法比较简单,主要作用就是初始化国际化文件。

那我们先来看案例:

1、配置两个文件

在这里插入图片描述

2、编写配置类

@Configuration
public class LifeConfiguration {

    // Bean 的名称必须要是 messageSource 
    @Bean(name = "messageSource")
    public MessageSource getMessageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.addBasenames("message", "message_en");
        return messageSource;
    }

}

3、测试

public class LifeMain {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(LifeConfiguration.class);

        MessageSource messageSource = applicationContext.getBean(MessageSource.class);

        String zhMessage = messageSource.getMessage("user.name", null, null, Locale.CHINA);
        String enMessage = messageSource.getMessage("user.name", null, null, Locale.ENGLISH);

        System.out.println("zhMessage = " + zhMessage);

        System.out.println("enMessage = " + enMessage);
    }

}

ok,现在知道使用了,那我们进入正题,源码分析。

切入口

initMessageSource();

org.springframework.context.support.AbstractApplicationContext#initMessageSource

protected void initMessageSource() {
    // 获取 BeanFactory
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();

    // 判断beanFactory中是否有名字为messageSource的bean
    // MESSAGE_SOURCE_BEAN_NAME = "messageSource";
    // 如果没有,新建DelegatingMessageSource类作为messageSource的Bean。
    // 如果有,从beanFactory中获取
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        // 从容器中获取 BeanName 为 messageSource 类型为 MessageSource 的 Bean 实例, 并将其赋值给当前容器内部的 MessageSource
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        // Make MessageSource aware of parent MessageSource.
        // 判断父类是否不为空 && 当前对象的 messageSource 是 HierarchicalMessageSource 的实例
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
            if (hms.getParentMessageSource() == null) {
                // Only set parent context as parent MessageSource if no parent MessageSource
                // registered already.
                // 将 HierarchicalMessageSource 的父 MessageSource 赋值为 getInternalParentMessageSource()
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Using MessageSource [" + this.messageSource + "]");
        }
    }
    else {
        // Use empty MessageSource to be able to accept getMessage calls.
        // 容器中不存在 BeanName 为 messageSource 的 Bean 实例
        // 手动创建一个 DelegatingMessageSource 实例, 用于接受 getMessage 方法调用。
        DelegatingMessageSource dms = new DelegatingMessageSource();
        // 添加父类 MessageSource
        dms.setParentMessageSource(getInternalParentMessageSource());
        // 将手动创建的 DelegatingMessageSource 赋值给当前容器中的 messageSource
        this.messageSource = dms;
        // 以 messageSource 为 BeanNme 将 DelegatingMessageSource 类的实例注册到一级缓存 singletonObjects 中
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
                         "': using default [" + this.messageSource + "]");
        }
    }
}

源码很简单,就是给 this.messageSource 属性赋值,但有一点我们要注意就是,手动注入 MessageSource 类型的 Bean 名称必须是 “messageSource”。

三、refresh 方法之 initApplicationEventMulticaster

这部分和 Spring 的事件监听机制有所关联,那我们按照惯例先来了解了解 Spring 的事件监听如何使用。

Spring 的事件监听主要分三部分:

  1. 事件:ApplicationEvent,要自定义事件,则需要创建一个类继承 ApplicationEvent。
  2. 事件发布者:ApplicationEventPublisher 和 ApplicationEventMulticaster,因为 ApplicationContext 实现了 ApplicationEventPublisher,所以事件发布可以直接使用 ApplicationContext。
  3. 事件监听器:ApplicationListener,通过创建一个实现了 ApplicationListener 并注册为 Spring bean 的类来接收消息。

既然如此,我们实现一个自己的监听器就需要完成下面三件事情:

  1. 自定义一个事件
  2. 向 IOC 容器中注册我们自己的监听器
  3. 发布事件

现在目标很明确了,那开始编写案例:

1、自定义事件

public class MyEvent extends ApplicationEvent {

    private String message;

    public MyEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

2、写一个自己的监听器,监听器的关注事件为 MyEvent

@Component
public class MyApplicationListener implements ApplicationListener<MyEvent> {

    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("MyApplicationListener 收到消息: " + event.getMessage());
    }
}

3、编写配置类

@Configuration
@ComponentScan(value = "cn.j3code.studyspring.listener")
public class MyListenerConfiguration {

}

4、测试

public class MyListenerMain {

    public static void main(String[] args) {
        // 读取配置文件启动
        AnnotationConfigApplicationContext annotationApplicationContext =
                new AnnotationConfigApplicationContext(MyListenerConfiguration.class);

        // 手动发布事件
        annotationApplicationContext.publishEvent(new MyEvent(annotationApplicationContext, "我发布的一个消息,记得关注点赞"));

    }
}

现在我们进入这个源码,看看其实现原理。

入口

initApplicationEventMulticaster();

org.springframework.context.support.AbstractApplicationContext#initApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
    // 获取 BeanFactory
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 判断 beanFactory 中是否存在事件广播中心bean实例
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        //存在时,beanFactory中的事件广播中心bean实例赋值给applicationEventMulticaster
        this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        // 不能存在,new 创建新的applicationEventMulticaster并赋值给applicationEventMulticaster
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        // 将创建的新事件广播中心bean实例注册到单例bean注册中心
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                         APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                         "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

该方法和 initMessageSource 方法步骤非常相似,先判断容器中是否存在对应的 Bean ,如果存在则不做处理,反之则向容器中添加相关 Bean。

当然 Spring 的事件监听机制在这里只是一个开始,还需要结合 registerListeners 方法才能实现监听功能,下节就来分析分析它。

四、refresh 方法之 onRefresh

空方法,需要子类实现

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

五、refresh 方法之 registerListeners

19 节中我们分析了多播器的初始化,而这次要介绍的就是向多播器中添加其它两个中要的组件:ListenersEvent

方法源码

org.springframework.context.support.AbstractApplicationContext#registerListeners

protected void registerListeners() {
    // Register statically specified listeners first.
    // 优先在事件多播器中 注册静态指定的监听器
    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) {
        // 获取事件多播器 ,并将实现ApplicationListener接口的Bean注册到applicationListenerBeans中
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // Publish early application events now that we finally have a multicaster...
    // earlyApplicationEvents是早期的事件,在Spring IOC整个生命周期中,比多播期的初始化要早出现
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    // 赋值为null, help gc
    this.earlyApplicationEvents = null;
    // 存储早期事件的集合被初始化
    if (earlyEventsToProcess != null) {
        // 遍历事件
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            // //添加到多播器中
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

方法很简单,就是向多播器中添加 Listeners 和 Event ,这样多播器对象就可以实现事件广播功能。

好了,今天的内容到这里就结束了,我是 【J3】关注我,我们下期见


  • 由于博主才疏学浅,难免会有纰漏,假如你发现了错误或偏见的地方,还望留言给我指出来,我会对其加以修正。

  • 如果你觉得文章还不错,你的转发、分享、点赞、留言就是对我最大的鼓励。

  • 感谢您的阅读,十分欢迎并感谢您的关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

J3code

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

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

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

打赏作者

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

抵扣说明:

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

余额充值