SpringBoot启动流程之(listener.starting())
- starting()流程图:
根据前面讲的SpringApplicationRunListeners listeners = getRunListeners(args);我们已经把所有事件都交给了广播
继续往后看,在系统获取完SpringApplicationRunListeners之后,紧接着便执行了starting方法,代码如下
SpringApplicationRunListeners listeners=getRunListeners(args); //SpringApplicationRunListeners执行了start方法 listeners.starting();
遍历SpringApplicationRunListeners的listener集合
class SpringApplicationRunListeners { private final Log log; //这里接受了一个以SpringApplicationRunListener为类型的List集合 private final List<SpringApplicationRunListener> listeners; //SpringApplicationRunListeners的默认构造,接受了一个子类型继承SpringApplicationRunListener的List SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) { this.log = log; this.listeners = new ArrayList<>(listeners); } //遍历listener集合 void starting() { for (SpringApplicationRunListener listener : this.listeners) { //启动listener,分派给SpringApplicationRunListener的具体实现EventPublishingRunListener listener.starting(); } } //下面还有很多方法,省略了。。。。。。逻辑基本上跟starting一样
- SpringApplicationRunListeners参数细节:
- 在start阶段,this.listeners只有一个为EventPublishingRunListener参数
- EventPublishingRunListener内部建立了广播SimpleApplicationEventMulticaster
- 广播内部拥有SpringApplication在构造的所有listener事件
来看看SpringApplicationRunListener的内部结构
public interface SpringApplicationRunListener { //run方法第一次启动时调用它 default void starting() { } //在环境建立好的时候调用它(建立environment对象) default void environmentPrepared(ConfigurableEnvironment environment) { } //建立ApplicationContext但是不引入配置信息 default void contextPrepared(ConfigurableApplicationContext context) { } //载入配置信息 default void contextLoaded(ConfigurableApplicationContext context) { } default void started(ConfigurableApplicationContext context) { } default void running(ConfigurableApplicationContext context) { } default void failed(ConfigurableApplicationContext context, Throwable exception) { } }
- 来看看EventPublishingRunListener类吧
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered { private final SpringApplication application; private final String[] args; private final SimpleApplicationEventMulticaster initialMulticaster; /** * application是new SpringApplication()时的构造方法的application,这里遍历的application.getListeners()就是构造 * 时读取以ApplicationListener.class为条件的META-INF/spring.factories的全限定类名集合 * @param application * @param args */ public EventPublishingRunListener(SpringApplication application, String[] args) { this.application = application; this.args = args; this.initialMulticaster = new SimpleApplicationEventMulticaster(); for (ApplicationListener<?> listener : application.getListeners()) { //将listener添加到this.defaultRetriever.applicationListeners里面,每一个listener内部进行了去重,防止相同事件的调用 this.initialMulticaster.addApplicationListener(listener); } } // 这个地方后面会说,其实从这里开始才是真正的开始启动listener public void starting() { this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args)); } //下面还有很多方法,基本上跟starting差不多 }
- 同样查看starting()方法,发现EventPublishingRunListener将所有事件委托给了SimpleApplicationEventMulticaster(事件多播实现类)
- 到此为止,事件的start的调用链路是理清了,看看它们之间的关系
- 总结
- 由SpringApplication创建SpringApplicationRunListeners,并且把经过构造的SpringApplication作为参数传递给了EventPublishingRunListener
- SpringApplicationRunListeners包含了SpringApplicationRunListener的list集合
- SpringApplicationRunListener的具体实现由EventPublishingRunListener实现
- EventPublishingRunListener最终把所有listener委托给了SimpleApplicationEventMulticaster实现
- 其实SpringApplicationRunListeners listeners = getRunListeners(args) ;阶段就是把SpringApplication构造阶段的listener交给了广播,为随后的start打下基础
- 事件由SimpleApplicationEventMulticaster多播器实现
public void multicastEvent(final ApplicationEvent event,@Nullable ResolvableType eventType){ //获取event的具体分派类型 ResolvableType type=(eventType!=null?eventType:resolveDefaultEventType(event)); Executor executor=getTaskExecutor(); //getApplicationListeners(event,type)会根据ResolvableType过滤我们需要的listener。接下来会讲 //遍历所有listener,并且把listener全部start for(ApplicationListener<?> listener:getApplicationListeners(event,type)){ //是否存在线程池支持异步执行 if(executor!=null){ executor.execute(()->invokeListener(listener,event)); } else{ //同步执行listener事件() invokeListener(listener,event); } } } //不重要 protected void invokeListener(ApplicationListener<?> listener,ApplicationEvent event){ ......省略 doInvokeListener(listener,event); ......省略 } //最终执行的是这个 private void doInvokeListener(ApplicationListener listener,ApplicationEvent event){ //所有的listener最终都是基于这个调用的,接下来看看onApplicationEvent(event);的庐山真面目 listener.onApplicationEvent(event); //省略......
- 根据ResolvableType过滤listeners
- 未过滤时的listeners
protected boolean supportsEvent( //根据当前listener类型加载不同的GenericApplicationListener实现 ApplicationListener<?> listener,ResolvableType eventType,@Nullable Class<?> sourceType){ //为listener配置GenericApplicationListener接口的具体实现 //如果当前listener与GenericApplicationListener存在关联,则类型转化为GenericApplicationListener //否则定义适配器GenericApplicationListenerAdapter为两者不兼容接口提供兼容 GenericApplicationListener smartListener=(listener instanceof GenericApplicationListener? (GenericApplicationListener)listener:new GenericApplicationListenerAdapter(listener)); //这两个方法则是进行具体的listener检测 return(smartListener.supportsEventType(eventType)&&smartListener.supportsSourceType(sourceType)); }
- 这是过滤后的listener
- (事件的真正执行)ApplicationListener#onApplicationEvent()
- 过滤的规则
//通过非适配器的过滤规则,这是Class自带的isAssignableFrom方法,用于确定type是否可以转换为supportedType private boolean isAssignableFrom(Class<?> type,Class<?>...supportedTypes){ if(type!=null){ for(Class<?> supportedType:supportedTypes){ if(supportedType.isAssignableFrom(type)){ return true; } } } return false; } //通过适配器的过滤规则则是通过ResolvableType.isAssignableFrom()方法或者通过 //ResolvableType.forClass(listenerType).as(ApplicationListener.class).getGeneric();来实现 //ResolvableType的过滤规则则是确定该类型能否在对象树上找到对应的指定对象
- 无论是通过Class、ResolvableType来实现过滤,其本质上都是在确定一个类型是否与指定类型存在关联(比如说继承、实现......)
- listeners的具体执行listener.onApplicationEvent(event);
/** * 由应用程序事件监听器实现的接口。基于 Observer 设计模式的标准 java.util.EventListener 接口。 * 从 Spring 3.0 开始,ApplicationListener 可以一般性地声明它感兴趣的事件类型。 * 当向 Spring ApplicationContext 注册时,事件将被相应地过滤,只有匹配事件对象才会调用侦听器。 * @param <E> */ @FunctionalInterface public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { //现在就是正真的开始start了,对于所有该接口的实现类, // 都可以在运行时根据具体创建类型执行onApplicationEvent,拓展性十分棒哦 void onApplicationEvent(E event); } -PS:过滤后执行的四个listener -LoggingApplicationListener(引导系统日志) -BackgroundPreinitializer(ApplicationListener 在耗时任务的后台线程中触发早期初始化) -LiquibaseServiceLocatorApplicationListener(说啥换版本?但是不晓得啥意思) -DelegatingApplicationListener(context.listener.classes下的listeners,不理解)