二、Springboot源码解析:创建SpringApplication对象(2)

一、什么是ApplicationContextInitializer?

首先看它的定义:

package org.springframework.context;
/**
 * Callback interface for initializing a Spring {@link ConfigurableApplicationContext}
 * prior to being {@linkplain ConfigurableApplicationContext#refresh() refreshed}.
 *
 * 

Typically used within web applications that require some programmatic initialization * of the application context. For example, registering property sources or activating * profiles against the {@linkplain ConfigurableApplicationContext#getEnvironment() * context's environment}. See {@code ContextLoader} and {@code FrameworkServlet} support * for declaring a "contextInitializerClasses" context-param and init-param, respectively. * *

{@code ApplicationContextInitializer} processors are encouraged to detect * whether Spring's {@link org.springframework.core.Ordered Ordered} interface has been * implemented or if the @{@link org.springframework.core.annotation.Order Order} * annotation is present and to sort instances accordingly if so prior to invocation. * * @author Chris Beams * @since 3.1 * @see org.springframework.web.context.ContextLoader#customizeContext * @see org.springframework.web.context.ContextLoader#CONTEXT_INITIALIZER_CLASSES_PARAM * @see org.springframework.web.servlet.FrameworkServlet#setContextInitializerClasses * @see org.springframework.web.servlet.FrameworkServlet#applyInitializers */ public interface ApplicationContextInitializer { /** * Initialize the given application context. * @param applicationContext the application to configure */ void initialize(C applicationContext); }

1、首先,它是一个接口
2、它是一个用于初始化ConfigurableApplicationContext的回调函数,并且会发生在ConfigurableApplicationContext.refresh()之前
3、一般被用在需要通过编程来初始化应用上下文的web应用,如注册属性资源和激活profile文件
4、支持解析其实例是否实现了org.springframework.core.Ordered接口,或者标记了org.springframework.core.annotation.Order注解,然后按照具体顺序执行初始化。
我们看到这个接口的定义用到了ConfigurableApplicationContext,那么它又是什么呢?

二、什么是ConfigurableApplicationContext?

要搞明白这个问题真的不容易,因为该接口及其父接口有着十分复杂的继承关系,如下:
二、Springboot源码解析:创建SpringApplication对象(2)_第1张图片
EnvironmentCapable:只声明了一个Environment getEnvironment()方法,许多Spring中的应用上下文都实现了此接口
BeanFactory:Bean容器
ListableBeanFactory:扩展了BeanFactory接口,可以从bean容器中获取想要的Bean
HierarchicalBeanFactory:扩展了BeanFactory接口,可以获取父容器,可以检测当前容器是否包含某个Bean
MessageSource:解析消息的策略接口,用于国际化
ApplicationEventPublisher:封装了事件发布功能
ResourceLoader:加载资源的策略接口
ResourcePatternResolver:模式资源解析器,eg:加载Ant-Style路径的资源
ApplicationContext:拥有以上接口的所有能力,并且提供了一些与application context相关的方法,例如获取上下文id,name,父上下文
Lifecycle:声明周期接口
AutoCloseable:只声明了一个close方法,用于自动关闭
Closeable:只提供了一个关闭方法
ConfigurableApplicationContext:大多数上下文都要实现的SPI接口
关于ConfigurableApplicationContext,官方文档是这样描述的:
SPI interface to be implemented by most if not all application contexts. Provides facilities to configure an application context in addition to the application context client methods in the org.springframework.context.ApplicationContext interface.Configuration and lifecycle methods are encapsulated here to avoid making them obvious to ApplicationContext client code. The present methods should only be used by startup and shutdown code.
(一个由大多数应用上下文实现的SPI接口。除了org.springframework.context.ApplicationContext提供了上下文的客户端方法之外,实现该SPI接口的应用还提供了配置应用上下文的基础设施;配置和生命周期方法被封装起来了是为了避免它们对于应用上下文客户端可见,当前的方法仅仅被启动和关闭的方法使用)
总而言之,我的理解就是该接口是一个SPI接口,给客户端配置上下文提供了一个切入点,供org.springframework.context.ApplicationContextInitializer#initialize回调。

三、什么是ApplicationListener?

在说清楚这个问题之前,有必要简单了解一下观察者设计模式和Java是如何基于观察者设计模式实现了事件监听。

1》观察者设计模式

按照我的理解,该模式有两个角色:观察者、被观察者;观察者维护一个被观察者列表,当事件发生时,观察者逐个通知被观察者:
二、Springboot源码解析:创建SpringApplication对象(2)_第2张图片

2》java的事件监听体系

具体有以下角色:
事件对象:java.util.EventObject
事件监听器:java.util.EventListener
最后自定义一个事件源(观察者),持有各个事件监听器(被观察者),当事件发生的时候,就通知各个事件监听器。

3》ApplicationListener

具体有以下角色:
事件对象:ApplicationEvent,在java.util.EventObject的基础上记录了事件发生的事件
事件监听器:ApplicationListener,限制了监听的事件必须要是ApplicationEvent

四、总结

不得不说,关于这几个接口,这里介绍的还是很抽象,但是源码的阅读或许就是这样,下面就一起来看看SpringApplication.run方法具体是如何使用这些接口的,或许我们可以得到一些启发。。。。。。

你可能感兴趣的:(springboot)