1.Run方法代码如下

StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        //创建DefualtBootstrapContext对象
        DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
        ConfigurableApplicationContext context = null;
        this.configureHeadlessProperty();
        //从这里开始,构建监听事件,并启动监听事件
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting(bootstrapContext, this.mainApplicationClass);

2.查看this.getRunListeners(args)代码

private SpringApplicationRunListeners getRunListeners(String[] args) {
		//这里再次出现getSpringFactoriesInstances方法,直接去缓存中拿到spring.factories中的配置类,并进行初始化
        Class<?>[] types = new Class[]{SpringApplication.class, String[].class};
        return new SpringApplicationRunListeners(logger, this.getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args), this.applicationStartup);
    }

3.查看getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args)的方法具体做了哪些事

splunk forwarder监听java服务日志 spring 启动监听_bootstrap


可以看见,从spring.factories中,找个了一个对应的事件,org.springframework.boot.context.event.EventPublishingRunListener,然后方法向下走的时候,通过反射创建此事件对象的创建,代码如下

private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) {
        List<T> instances = new ArrayList(names.size());
        Iterator var7 = names.iterator();

        while(var7.hasNext()) {
            String name = (String)var7.next();

            try {
                Class<?> instanceClass = ClassUtils.forName(name, classLoader);
                Assert.isAssignable(type, instanceClass);
                Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
                //这里开始进行对象的创建
                T instance = BeanUtils.instantiateClass(constructor, args);
                instances.add(instance);
            } catch (Throwable var12) {
                throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, var12);
            }
        }

        return instances;
    }

4.查看EventPublishingRunListener的构造方法

public EventPublishingRunListener(SpringApplication application, String[] args) {
		//这里将SpringApplication对象赋值到application属性,并获取SpringApplication对象中的listener
        this.application = application;
        this.args = args;
        this.initialMulticaster = new SimpleApplicationEventMulticaster();
        //application中的listener对象进行迭代,并加入到EventPublishingRunListener类的广播属性中
        Iterator var3 = application.getListeners().iterator();

        while(var3.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var3.next();
            this.initialMulticaster.addApplicationListener(listener);
        }
    }

上一章SpringApplication对象构建中,已经提到了listener属性有哪些值,这里就不再阐述,直接贴图

splunk forwarder监听java服务日志 spring 启动监听_bootstrap_02


可以看到这里有9个Listener,我们看下this.initialMulticaster.addApplicationListener(listener);这一行代码做了哪些事

public void addApplicationListener(ApplicationListener<?> listener) {
        AbstractApplicationEventMulticaster.DefaultListenerRetriever var2 = this.defaultRetriever;
        synchronized(this.defaultRetriever) {
            Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
            if (singletonTarget instanceof ApplicationListener) {
                this.defaultRetriever.applicationListeners.remove(singletonTarget);
            }
			//将这9个Listener添加到defaultRetriever对象的applicationListeners属性中,
			这个属性是一个LinkedHashSet
            this.defaultRetriever.applicationListeners.add(listener);
            this.retrieverCache.clear();
        }
    }

到这里this.getSpringFactoriesInstances方法基本执行结束,之后再创建SpringApplicationRunListeners对象,看一下SpringApplicationRunListener对象到构造方法

SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners, ApplicationStartup applicationStartup) {
        this.log = log;
        //这里到listeners就是封装好的EventPublishingRunListener对象
        this.listeners = new ArrayList(listeners);
        this.applicationStartup = applicationStartup;
    }

splunk forwarder监听java服务日志 spring 启动监听_Startup_03


这里我们可以看到SpringApplicationRunListeners的listener属性已经赋值了构建好的EventPublishingRunListener,下一步我们SpringApplicationRunListeners的starting方法

5.查看SpringApplicationRunListeners的starting方法代码

void starting(ConfigurableBootstrapContext bootstrapContext, Class<?> mainApplicationClass) {
		//这里使用了Java8的Consumer接口,函数式编程
        this.doWithListeners("spring.boot.application.starting", (listener) -> {
            listener.starting(bootstrapContext);
        }, (step) -> {
            if (mainApplicationClass != null) {
                step.tag("mainApplicationClass", mainApplicationClass.getName());
            }

        });
    }
    	//我们看一下这个doWithListeners方法
	    /*
	    	第一个参数式一个stepName,传入的字符串spring.boot.application.starting
	    	第二个参数是Consumer<SpringApplicationRunListener> listenerAction
	    	(listener) -> {
	            listener.starting(bootstrapContext);
	        }
	        方法里面this.listeners.forEach(listenerAction);就是将SpringApplicationRunListener中的listener循环的调用starting方法,这里的listener就只有一个对象EventPublishingRunListener,所以就会调用该对象的starting方法
	    */
     private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> 		listenerAction, Consumer<StartupStep> stepAction) {
        StartupStep step = this.applicationStartup.start(stepName);
        this.listeners.forEach(listenerAction);
        if (stepAction != null) {
            stepAction.accept(step);
        }

        step.end();
    }

6.我们看一下EventPublishingRunListener的starting方法

//这里,创建了一个ApplicationStartingEvent事件对象,事件对象的构建方法中,将SpringApplication设置为source属性,可见下图
public void starting(ConfigurableBootstrapContext bootstrapContext) {
        this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
    }

splunk forwarder监听java服务日志 spring 启动监听_bootstrap_04


我们看一下multicastEvent方法

public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
        //这里获取Executor接口实现,默认为null,可以给这个taskExecutor设置自定义的Executor实现多线		程处理
        Executor executor = this.getTaskExecutor();
        //这里返回的迭代器是listener迭代
        Iterator var5 = this.getApplicationListeners(event, type).iterator();
        while(var5.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var5.next();
            if (executor != null) {
                executor.execute(() -> {
                    this.invokeListener(listener, event);
                });
            } else {
            //这里调用SpringApplication中的listener
                this.invokeListener(listener, event);
            }
        }

    }
    //代码debug到this.invokeListener(listener,event)
   

```java
 	private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
        try {
       		//可以看到这里调用了每一个listener自己的onApplicationEvent方法,启动事件监听
            listener.onApplicationEvent(event);
        } catch (ClassCastException var6) {
            String msg = var6.getMessage();
            if (msg != null && !this.matchesClassCastMessage(msg, event.getClass()) && (!(event instanceof PayloadApplicationEvent) || !this.matchesClassCastMessage(msg, ((PayloadApplicationEvent)event).getPayload().getClass()))) {
                throw var6;
            }

            Log loggerToUse = this.lazyLogger;
            if (loggerToUse == null) {
                loggerToUse = LogFactory.getLog(this.getClass());
                this.lazyLogger = loggerToUse;
            }

            if (loggerToUse.isTraceEnabled()) {
                loggerToUse.trace("Non-matching event type for listener: " + listener, var6);
            }
        }

    }

到此,Springboot启动流程中,事件监听就结束了!!!