springboot2.1.1 启动过程的事件驱动模型

本文章基于springboot2.1.1

1 启动

@SpringBootApplication
@ServletComponentScan
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}
public static ConfigurableApplicationContext run(Class<?> primarySource,
	String... args) {
	return run(new Class<?>[] { primarySource }, args);
}
public static ConfigurableApplicationContext run(Class<?>[] primarySources,
	String[] args) {
	return new SpringApplication(primarySources).run(args);
}
public SpringApplication(Class<?>... primarySources) {
		this(null, primarySources);
	}

2 SpringApplication的构造

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
	this.resourceLoader = resourceLoader;
	Assert.notNull(primarySources, "PrimarySources must not be null");
	//将primarySources即我们自己写的启动类放入set中
	this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
	//从类路径中判断应用程序类型
	this.webApplicationType = WebApplicationType.deduceFromClasspath();
	//由接口获取其实现类的对象实例
	//从META-INF/spring.factories文件中获取ApplicationContextInitializer接口的实现类
	//利用反射创建所有实现类的对象存放到变量initializers,List集合中
	setInitializers((Collection) getSpringFactoriesInstances(
		ApplicationContextInitializer.class));
	//同上
	setListeners((Collection) getSpringFactoriesInstances(
		ApplicationListener.class));
	//通过获取当前调用栈,找到main方法所在的类,即为启动类
	this.mainApplicationClass = deduceMainApplicationClass();
}

当前栈中储存了正在运行的方法的方法信息

2.1 从类路径中判断应用程序类型

private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",
		"org.springframework.web.context.ConfigurableWebApplicationContext" };

private static final String WEBMVC_INDICATOR_CLASS = "org.springframework."
		+ "web.servlet.DispatcherServlet";

private static final String WEBFLUX_INDICATOR_CLASS = "org."
		+ "springframework.web.reactive.DispatcherHandler";

private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";

private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";

private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
static WebApplicationType deduceFromClasspath() {
	if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
			&& !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
			&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
		return WebApplicationType.REACTIVE;
	}
	for (String className : SERVLET_INDICATOR_CLASSES) {
		if (!ClassUtils.isPresent(className, null)) {
			return WebApplicationType.NONE;
		}
	}
	return WebApplicationType.SERVLET;
}

三种返回类型解释:

  1. return WebApplicationType.NONE :不是Web应用程序
  2. return WebApplicationType.SERVLET :基于servlet的Web应用程序
  3. WebApplicationType.REACTIVE :响应式的Web应用程序

2.2 由接口获取其实现类的对象实例

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
	return getSpringFactoriesInstances(type, new Class<?>[] {});
}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
	Class<?>[] parameterTypes, Object... args) {
	//获取类加载器
	ClassLoader classLoader = getClassLoader();
	//获取type的实现类的全限定名,存储在set中确保每一个全限定名是唯一的
	Set<String> names = new LinkedHashSet<>(
		SpringFactoriesLoader.loadFactoryNames(type, classLoader));
	//创建type的实现类的对象
	List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
		classLoader, args, names);
	//进行排序
	AnnotationAwareOrderComparator.sort(instances);
	return instances;
}

3 执行run方法

SpringApplication构造完后就执行run

public ConfigurableApplicationContext run(String... args) {
	//StopWatch是org.springframework.util的工具类,可以用来记录程序的运行时间
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	//spring容器
	ConfigurableApplicationContext context = null;
	Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
	//设置SYSTEM_PROPERTY_JAVA_AWT_HEADLESS为true
	configureHeadlessProperty();
	//从META-INF/spring.factories文件中得到SpringApplicationRunListener接口的所有实现类对象实例集合
	//该对象持有SpringApplicationRunListener对象的集合,统一管理SpringApplicationRunListener
	SpringApplicationRunListeners listeners = getRunListeners(args);
	//发布ApplicationStartingEvent事件,
	listeners.starting();
	//springboot启动时的事件驱动模型先到此
	//----------------------------------------
	//下面先不用管,下面是spring容器的创建
	...
}

3.1 getRunListeners(String[] args)

private SpringApplicationRunListeners getRunListeners(String[] args) {
	Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
	//这里有从META-INF/spring.factories文件中获取SpringApplicationRunListener接口的实现类
	//将类的对象实例传入SpringApplicationRunListeners的构造器中
	return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
			SpringApplicationRunListener.class, types, this, args));
}

这里的getSpringFactoriesInstances方法比上面多了SpringApplication.class和String[].class组成的Class数组type、this、args,这些为创建SpringApplicationRunListener实现类对象时的参数。

3.1.1 SpringApplicationRunListeners的构造

SpringApplicationRunListeners(Log log,
	Collection<? extends SpringApplicationRunListener> listeners) {
	this.log = log;
	this.listeners = new ArrayList<>(listeners);
}

3.2 listeners.starting()

public void starting() {
	for (SpringApplicationRunListener listener : this.listeners) {
		listener.starting();
	}
}
public void starting() {
	//this.initialMulticaster就是SimpleApplicationEventMulticaster
	//使用SimpleApplicationEventMulticaster发布事件ApplicationStartingEvent
	//ApplicationStartingEvent的source是SpringApplication
	this.initialMulticaster.multicastEvent(
			new ApplicationStartingEvent(this.application, this.args));
}
public void multicastEvent(ApplicationEvent event) {
	//将ApplicationStartingEvent封装成ResolvableType
	multicastEvent(event, resolveDefaultEventType(event));
}

ResolvableType对象
event 封装成ResolvableType,该类提供方法可以得到父类,接口,以及通用参数。四种方法的到该对象:

  1. forField(Field)
  2. forMethodParameter(Method, int)
  3. forMethodReturnType(Method)
  4. forClass(Class)

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
	ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
	//getApplicationListeners()是由ApplicationEvent和ResolvableType得到监听该种事件的ApplicationListener集合
	for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
		Executor executor = getTaskExecutor();
		if (executor != null) {
			executor.execute(() -> invokeListener(listener, event));
		}
		else {
			//执行监听器的响应方法
			invokeListener(listener, event);
		}
	}
}

4 总结

     启动springboot,先会实例化 SpringApplication ,再执行 SpringApplicationrun 方法, run 方法里面通过 getRunListeners(args) 方法获得了在META-INF/spring.factories文件中实现SpringApplicationRunListener接口的类的对象实例集合。
     遍历这个集合,执行每一个SpringApplicationRunListenerstarting() 方法,使用SimpleApplicationEventMulticastermulticastEvent(event) 方法发布ApplicationStartingEvent 事件。
     multicastEvent(event) 方法里通过getApplicationListeners(event, type) 找出事件的监听者,在通过invokeListener(listener, event) 执行监听者的的响应方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值