天天看点

Spring refresh 方法分析之三

一、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、配置两个文件

Spring refresh 方法分析之三

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 节中我们分析了多播器的初始化,而这次要介绍的就是向多播器中添加其它两个中要的组件:​

​Listeners​

​​、​

​Event​

​ 。

方法源码

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);
        }
    }
}