1.Springboot之ApplicationContext&Listener&Config

13 篇文章 0 订阅
12 篇文章 0 订阅

Springboot启动过程中在刷新IOC容器之前主要包括三大部分功能完善:ApplicationContextInitializerApplicationListenerEnvironmentPostProcessor

ApplicationContextInitializer 主要用在容器刷新之前调用改接口实现类的 initialize 方法,并将 ConfigurableApplicationContext 类的实例作为参数传入。通常用于根据应用上下文进行处理的编程中。且实现类可以通过 Ordered 接口或 @Order 注解 进行多个 Initializer 的排序。

public class SpringApplication {
	private List<ApplicationContextInitializer<?>> initializers;
	private List<ApplicationListener<?>> listeners;
	
	public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
	}
	
	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		...
		//初始化ApplicationContextInitializer
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		//初始化应用监听器AnnotationConfigServletWebServerApplicationContext
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
	}
	
	public ConfigurableApplicationContext run(String... args) {
		...
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
		// 实例化StandardServletEnvironment
		ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
		//实例化应用上下文
		ConfigurableApplicationContext context = createApplicationContext();
		//应用上下文与StandardServletEnvironment的绑定操作
		prepareContext(context, environment, listeners, applicationArguments, printedBanner);
		refreshContext(context);
		afterRefresh(context, applicationArguments);
		listeners.started(context);
		callRunners(context, applicationArguments);
		listeners.running(context);
		return context;
	}
	
	private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
			ApplicationArguments applicationArguments) {
		// Create and configure the environment
		ConfigurableEnvironment environment = getOrCreateEnvironment();
		configureEnvironment(environment, applicationArguments.getSourceArgs());
		ConfigurationPropertySources.attach(environment);
		//执行ApplicationListener类型的监听器
		listeners.environmentPrepared(environment);
		// 利用上述得到的配置value动态控制SpringApplication实例中属性值
		bindToSpringApplication(environment);
		....
		ConfigurationPropertySources.attach(environment);
		return environment;
	}
	
	private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
		context.setEnvironment(environment);
		postProcessApplicationContext(context);
		// 执行各种类型的ApplicationContextInitializer
		applyInitializers(context);
		listeners.contextPrepared(context);
		if (this.logStartupInfo) {
			logStartupInfo(context.getParent() == null);
			logStartupProfileInfo(context);
		}
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		...
		Set<Object> sources = getAllSources();
		load(context, sources.toArray(new Object[0]));
		listeners.contextLoaded(context);
	}
}

在SpringApplication的构造器中通过Spi机制获取到类名之后,通过反射完成实例化。对参数initializerslisteners进行复制。具体取值如spring.factories文件:

核心spring-boot.jar、spring-beans.jar包下的spring.factories文件。

1、自定义ApplicationContextInitializer

spring-boot.jar#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
@Slf4j
public class CustomApplicationContextInitializer implements ApplicationContextInitializer {
    @Override//AnnotationConfigServletWebServerApplicationContext
    public void initialize(ConfigurableApplicationContext applicationContext) {
        log.error("========== this is custom applicationContextInitializer ===============");
    }
}

Apollo之ApolloApplicationContextInitializer

1.1、方式一

SpringApplication springApplication = new SpringApplication(BootApp.class);
springApplication.addInitializers(new CustomApplicationContextInitializer());
ConfigurableApplicationContext run = springApplication.run(args);

1.2、方式二

SPI 扩展 META-INF/spring.factories:

org.springframework.context.ApplicationContextInitializer=\
  boot.initializer.Custom3ApplicationContextInitializer

1.3、方式三

在配置文件 application.properties 中添加如下配置:

context.initializer.classes = boot.initializer.Custom2ApplicationContextInitializer

2.ApplicationListener

spring-boot.jar#spring.factories部分内容如下:

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

比较常见的内置监听器包括ConfigFileApplicationListenerBootstrapApplicationListener等。

3.EnvironmentPostProcessor

spring-boot.jar#spring.factories部分内容如下:

org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor,\
com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer

目前只发现在执行ConfigFileApplicationListener监听器时涉及该类型的后置处理器。示例参考Apollo之ApolloApplicationContextInitializer。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值