调试途中,发现初始化发生了两次,最后发现是在springboot启动的prepareEnvironment过程中,在LoggingApplicationListener执行之前,会有一个BootstrapApplicationListener先处理ApplicationEnvironmentPreparedEvent 在这里插入图片描述

BootstrapApplicationListener是一个通过在单独的引导上下文(bootstrap context)中委托 ApplicationContextInitializer bean 来准备 SpringApplication(例如填充其环境)的侦听器。

bootstrap context是从 spring.factories 中定义为 BootstrapConfiguration 的源创建的 SpringApplication, 此刻配置文件读到的是bootstrap.properties或bootstrap.yml的内容,而不是application.properties

public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
		ConfigurableEnvironment environment = event.getEnvironment();
		//spring.cloud.bootstrap.enabled为false则不进行引导
		if (!environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class,
				true)) {
			return;
		// don't listen to events in a bootstrap context
		if (environment.getPropertySources().contains(BOOTSTRAP_PROPERTY_SOURCE_NAME)) {
			return;
		ConfigurableApplicationContext context = null;
		//读取{spring.cloud.bootstrap.name:bootstrap}默认是bootstrap
		String configName = environment
				.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");
		for (ApplicationContextInitializer<?> initializer : event.getSpringApplication()
				.getInitializers()) {
			if (initializer instanceof ParentContextApplicationContextInitializer) {
				context = findBootstrapContext(
						(ParentContextApplicationContextInitializer) initializer,
						configName);
		if (context == null) {
		//创建引导类上下文环境
			context = bootstrapServiceContext(environment, event.getSpringApplication(),
					configName);
			event.getSpringApplication()
					.addListeners(new CloseContextOnFailureApplicationListener(context));
		apply(context, event.getSpringApplication(), environment);
  1. spring.cloud.bootstrap.enabled为false则不进行引导
  2. 读取{spring.cloud.bootstrap.name:bootstrap}默认是bootstrap作为配置文件
  3. 创建引导类上下文环境
  4. 在3中通过final ConfigurableApplicationContext context = builder.run();调用run方法

所以如果有读者调试的时候发现第一次通过LoggingApplicationListener的各个阶段找不到自己配置的logback配置文件,原因是先进行了
BootstrapApplicationListener的事件处理,此刻的配置文件和环境变量都是bootstrap的,所以读不到我们自己的配置文件和环境变量(application)

bootstrap和application有什么区别

在springcloud的源码文档中有说明

  1. Spring Cloud 构建于 Spring Boot 之上,在 Spring Boot 中有两种上下文,一种是 bootstrap,另外一种是 application
  2. application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。
  3. bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。
  4. bootstrap 主要用于从额外的资源来加载配置信息,还可以在本地外部配置文件中解密属性。
  5. 这两个上下文共用一个环境,它是任何Spring应用程序的外部属性的来源。
  6. bootstrap 里面的属性会优先加载,它们默认也不能被本地相同配置覆盖。
  7. boostrap 由父 ApplicationContext 加载,比 applicaton 优先加载
  8. boostrap 里面的属性不能被覆盖

bootstrap 配置文件有以下几个应用场景:

  1. 使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;apollo做配置中心时同理
  2. 些固定的不能被覆盖的属性
  3. 些加密/解密的场景;

启动上下文时,Spring Cloud会创建一个Bootstrap Context,作为Spring应用的Application Context的父上下文。初始化的时候,Bootstrap Context==负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的Environment。Bootstrap属性有高优先级,默认情况下,它们不会被本地配置覆盖。 Bootstrap context和Application Context有着不同的约定,所以新增了一个bootstrap.yml文件,而不是使用application.yml (或者application.properties)。保证Bootstrap Context和Application Context配置的分离。

分享的文件包括Logback的相关jar包和核心配置文件。 Logback是由log4j创始人设计的另一个开源日志组件,基于slf4j的日志规范实现的框架,性能比log4j要好。 Logback主要分为三个技术模块: logback-core:该模块为其他两个模块奠定了基础。 logback-classic:是log4j的一个改良版本,同时它完整实现了slf4j API。 logback-access 模块与 Tomcat 和 Jetty 等 Servlet 容器集成,以提供 HTTP 访问日志功能。
1、首先在bootstrap.yml文件添加如下配置: logging.config: classpath:logback-spring.xml //配置各个环境使用的log配置文件 logback.path: /home/work/logs //配置相应的环境log打印路径 2、不同环境动态配置日志路径和级别 动态配置日志打印路径:使用springProperty属性,source配置对应的yml文件的配置 <springProperty scope="context" na
<springProperty name="ES_URL" source="logging.es-url"/> <springProperty name="ES_PORT" source="logging.es-port"/> <destination>${ES_URL:- }:${ES_PORT:- }</destination>
最近工作中需要部署日志管理平台,我们打算采用FileBeat+Logstash+ElasticSearch+Kibana进行搭建,通过FileBeat进行日志收集,Logstash进行日志过滤,我们需要在SpringBoot工程中配置logback输出日志,这里我记录一下logback具体配置,便于日后查阅。 <?xml version="1.0" encoding="UTF-8"?&g...
SpringBoot项目引入SpringClouds时run方法被执行的两次解析 在没用引入SpringCloud之前,可以看到environment资源实例是:StandardServletEnvironment 引入SpringClound之后,会发现第一次environment资源实例是:StandardEnvironment,第二次资源实例才是StandardServletEnviron...
Spring Boot是目前非常流行的Java Web应用开发框架之一,其内置的日志框架Logback也是非常重要的一部分。在源码分析方面,我们可以通过阅读Spring BootLogback的官方文档以及相关的开源代码库来深入了解其实现机制和使用方法。 在Logback中,主要的核心组件包括Logger、Appender和Layout。Logger是日志记录器,用于记录应用程序的日志信息;Appender是日志输出器,将日志信息输出到指定的地方,比如控制台、文件、数据库等;Layout是日志格式化器,用于将日志信息格式化成指定的输出格式。在Logback中,这三个组件是通过配置文件来进行管理和配置的。 而在Spring Boot中,Logback的使用也是非常简单的。一般来说,我们只需要在配置文件中加入一些特定的配置项,如logging.file指定日志输出到文件中,logging.level指定日志输出的级别等等。对于部分自定义需求,我们可以通过配置Logback的默认配置文件logback-spring.xml或者logback.xml来自定义相关的配置项,如修改日志格式、添加Appender等等。 在源码分析方面,我们可以先从Spring BootLogback自身的源码入手,理解其设计思想和实现机制。同时,可以通过开源社区中的相关代码库,如spring-boot-starter-logging、logback等来深入研究它们的具体实现方法和使用技巧。最终,我们可以通过结合实际项目的应用场景,加深对Spring BootLogback的理解和应用。