Spring源码2:发布启动事件进行业务的监控与拓展

在spring boot实现对监控与拦截器的aop切入spring boot提供了两大种监控的切入方式:

1. 发布启动事件ApplicationStartingEvent

    1.1 SpringApplicationRunListeners源码

    1.2 EventPublishingRunListener源码

    1.3 SimpleApplicationEventMulticaster源码

2. 启动事件的监听器

    2.1 LoggingApplicationListener

    2.2 BackgroundPreinitializer

    2.3 DelegatingApplicationListener

    2.4 LiquibaseServiceLocatorApplicationListener

现在我针对两方式进行进行监控的aop切入分别为:

1、实现ApplicationListener接口的方式,

2、实现SpringApplicationRunListener接口的方式

在spring boot中其将监听器加入到启动过程中主要是通过

//spring boot容器启动加载过程入口
public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        FailureAnalyzers analyzers = null;
        this.configureHeadlessProperty();
        //加载Spring启动过程需要加载的事件
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        
        //启动监听事件
        listeners.starting();

        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            new FailureAnalyzers(context);
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            listeners.finished(context, (Throwable)null);
            stopWatch.stop();
            if(this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, listeners, (FailureAnalyzers)analyzers, var9);
            throw new IllegalStateException(var9);
        }
    }

3.1针对ApplicationListener接口实现方式的监听启动器,

使用SpringApplication#setListeners方法添加监听器SpringApplication#setListeners(..[])或者addListeners(..)

使用泛型构造专门接收ApplicationStartedEvent事件的监听器

@SpringBootApplication
@EnableEurekaServer
@EnableDiscoveryClient
public class EurekaServerApplication {

	public static void main(String[] args) {

		SpringApplication application = new SpringApplication(EurekaServerApplication.class);
                
                //将监听加载入启动过程
		application.addListeners(new MyStartListner());
		application.run(args);
//		SpringApplication.run(EurekaServerApplication.class, args);
	}

}

3.2、实现SpringApplicationRunListener接口方式

由于SpringApplication没有提供add或者set监听器的方法,需要通过配置的加载信息实现对监听SpringApplicationRunListener的切入

文件目录结构如下:

InitializationMonitor代码如下:

package com.wangyong.learn.cloudframe.eurekaserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

/**
 * Created by Administrator on 2019/8/7.
 */
public class InitializationMonitor implements SpringApplicationRunListener {

    public InitializationMonitor(SpringApplication springApplication,String... args) {
    }

    public InitializationMonitor() {
    }

    @Override
    public void starting() {
        System.out.println("监听器启动");
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment configurableEnvironment) {
        System.out.println("监听器环境准备");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("监听器上下文准备");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("加载上下文");
    }

    @Override
    public void finished(ConfigurableApplicationContext configurableApplicationContext, Throwable throwable) {
        System.out.println("监听器加载完成");
    }
}

注意这个类中,我们不光实现了SpringApplicationRunListener接口所要求的7个方法,还添加了一个以SpringApplication和一个变长字符串数组为参数的构造方法。那么,在哪里规定,必须要有这样一个构造方法呢?注意getRunListeners中的代码:

public class SpringApplication
private SpringApplicationRunListeners getRunListeners(String[] args) {
        Class<?>[] types = new Class[]{SpringApplication.class, String[].class};
        return new SpringApplicationRunListeners(logger, this.getSpringFactoriesInstances(SpringApplicationRunListener.class, types, new Object[]{this, args}));
    }

注意types的定义,这个定义,决定了如果没有相应的构造方法,就会报错。

spring.factories文件中配置如下:

#配置监听器
org.springframework.boot.SpringApplicationRunListener=\com.wangyong.learn.cloudframe.eurekaserver.InitializationMonitor

总结

Spring应用运行时监听器和普通的监听器相比,它给不同的事件提供了不同的接口方法,使用起来会更加清晰明了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值