Springboot框架中提供了两种类型的应用上下文ApplicationContext,分别为:

  • AnnotationConfigServletWebServerApplicationContext。
  • AnnotationConfigReactiveWebServerApplicationContext。
public class SpringApplication {
	
	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories();
		//获取接口ApplicationContextInitializer的所有实现类
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

	public ConfigurableApplicationContext run(String... args) {
		...
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting(bootstrapContext, this.mainApplicationClass);
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
		ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
		//实例化ApplicationContext实例
		context = createApplicationContext();
		prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
		refreshContext(context);
		return context;
	}

	private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {
		//应用上下文持有Environment
		context.setEnvironment(environment);
		postProcessApplicationContext(context);
		// ApplicationContextInitializer接口核心方法之initialize方法
		applyInitializers(context);
        // 监听器触发 ApplicationContextInitializedEvent类型的事件
		listeners.contextPrepared(context);
		...
	}
 	
}

2.ApplicationContextInitializer

这是一个跟应用上下文相关的回调接口,其目的是优先为应用上下文ApplicationContext做一些初始化功能。比较典型的是web应用中通过回调接口为ApplicationContext做一些计划性的初始化工作。例如为ApplicationContext的Environment属性注册property sources or activating profiles等。

@FunctionalInterface
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {
	void initialize(C applicationContext);
}

SpringBoot框架通过spring.factories文件默认提供了如下子类:

org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer,
com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer

这些子类的加载时机为类SpringApplication的构造方法。

public class SpringApplication {
	protected void applyInitializers(ConfigurableApplicationContext context) {
		for (ApplicationContextInitializer initializer : getInitializers()) {
			Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),ApplicationContextInitializer.class);
			initializer.initialize(context);
		}
	}
}

3.ApplicationContextInitializedEvent

SpringBoot框架内部并没有内置监听器ApplicationListener处理该类型的事件。

public class ApplicationContextInitializedEvent extends SpringApplicationEvent {

	private final ConfigurableApplicationContext context;

	public ApplicationContextInitializedEvent(SpringApplication application, String[] args,ConfigurableApplicationContext context) {
		super(application, args);
		this.context = context;
	}

	public ConfigurableApplicationContext getApplicationContext() {
		return this.context;
	}

}

用户可以实现支持该事件类型的监听器ApplicationListener。如上所示监听器处理该事件时是基于SpringApplication类、运行参数或者应用参数、ConfigurableApplicationContext。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部