当前位置:   article > 正文

深入SpringBoot源码(八)SpringApplication与Environment绑定的前置工作(中)_spring environment 和 springapplication

spring environment 和 springapplication

在这里插入图片描述
在这里插入图片描述
SpringApplicationRunListeners有以下几个成员字段:

	//org.apache.commons.logging.Log
	private final Log log;

	private final List<SpringApplicationRunListener> listeners;

	private final ApplicationStartup applicationStartup;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

SpringApplicationRunListeners可看作是SpringApplicationRunListener的组合模式实现,SpringApplicationRunListener。SpringApplicationRunListener是SpringApplication运行方法的监听器,SpringApplication每次运行都会创建一个新的SpringApplicationRunListener实例。
在这里插入图片描述
ApplicationStartup 来标记应用程序启动期间的步骤,并收集有关执行上下文或其处理时间的数据。

public interface ApplicationStartup {

	/**
	 * 默认“无操作”ApplicationStartup 实现。
	 * 此变体旨在最小化开销,并且不记录数据。
	 */
	ApplicationStartup DEFAULT = new DefaultApplicationStartup();

	/**
	 * 创建一个新步骤并标记它的开始。步骤名称描述当前操作或阶段。
	 * 这个技术名称应该是“.”命名空间,并且可以在应用程序启动期间重用于描述同一步骤的其他实例。
	 * @param name 步骤名称	 
	 */
	StartupStep start(String name);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述
默认“无操作”ApplicationStartup 实现。此变体旨在最小化开销,并且不记录事件。

class DefaultApplicationStartup implements ApplicationStartup {

	private static final DefaultStartupStep DEFAULT_STARTUP_STEP = new DefaultStartupStep();

	@Override
	public DefaultStartupStep start(String name) {
		return DEFAULT_STARTUP_STEP;
	}


	static class DefaultStartupStep implements StartupStep {

		private final DefaultTags TAGS = new DefaultTags();

		@Override
		public String getName() {
			return "default";
		}

		@Override
		public long getId() {
			return 0L;
		}

		@Override
		public Long getParentId() {
			return null;
		}

		@Override
		public Tags getTags() {
			return this.TAGS;
		}

		@Override
		public StartupStep tag(String key, String value) {
			return this;
		}

		@Override
		public StartupStep tag(String key, Supplier<String> value) {
			return this;
		}

		@Override
		public void end() {

		}


		static class DefaultTags implements StartupStep.Tags {

			@Override
			public Iterator<StartupStep.Tag> iterator() {
				return Collections.emptyIterator();
			}
		}
	}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

DefaultApplicationStartup的静态内部类DefaultStartupStep实现了StartupStep接口。SpringApplicationRunListeners的environmentPrepared方法源码:

	void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
		doWithListeners("spring.boot.application.environment-prepared",
				(listener) -> listener.environmentPrepared(bootstrapContext, environment));
	}

	private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction) {
		doWithListeners(stepName, listenerAction, null);
	}

	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();
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述
这里调用的是DefaultApplicationStartup的start方法,必须通过DefaultApplicationStartup的start方法才能访问DefaultStartupStep。

	private static final DefaultStartupStep DEFAULT_STARTUP_STEP = new DefaultStartupStep();

	@Override
	public DefaultStartupStep start(String name) {
		return DEFAULT_STARTUP_STEP;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们来看看doWithListeners(String stepName, Consumer listenerAction)方法,这个方法的第二个参数是一个函数式接口,SpringApplicationRunListeners的environmentPrepared方法对其传入的参数是(listener) -> listener.environmentPrepared(bootstrapContext, environment),所以Consumer的accept方法接收类型是SpringApplicationRunListener。在doWithListeners(String stepName, Consumer listenerAction,Consumer stepAction)方法中,会遍历每一个成员字段listeners,并且调用每一个listener的environmentPrepared方法。
在这里插入图片描述
我这里演示的demo只有一个listener实例,类型是EventPublishingRunListener,这个listener来自SpringApplication的getRunListeners方法

	private SpringApplicationRunListeners getRunListeners(String[] args) {
		Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
		return new SpringApplicationRunListeners(logger,
				getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),
				this.applicationStartup);
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

而getRunListeners又调用了getSpringFactoriesInstances加载了spring-boot-2.6.3.jar中的spring.factories文件key是SpringApplicationRunListener的实例。
在这里插入图片描述
SpringApplicationRunListener 发布 SpringApplicationEvents。对在实际刷新上下文之前触发的事件使用内部 ApplicationEventMulticaster。
在这里插入图片描述
EventPublishingRunListener的源码:

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {

	private final SpringApplication application;

	private final String[] args;

	private final SimpleApplicationEventMulticaster initialMulticaster;

	public EventPublishingRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
		for (ApplicationListener<?> listener : application.getListeners()) {
			this.initialMulticaster.addApplicationListener(listener);
		}
	}

	@Override
	public int getOrder() {
		return 0;
	}

	@Override
	public void starting(ConfigurableBootstrapContext bootstrapContext) {
		this.initialMulticaster
				.multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
	}

	@Override
	public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
			ConfigurableEnvironment environment) {
		this.initialMulticaster.multicastEvent(
				new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.application, this.args, environment));
	}

	@Override
	public void contextPrepared(ConfigurableApplicationContext context) {
		this.initialMulticaster
				.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));
	}

	@Override
	public void contextLoaded(ConfigurableApplicationContext context) {
		for (ApplicationListener<?> listener : this.application.getListeners()) {
			if (listener instanceof ApplicationContextAware) {
				((ApplicationContextAware) listener).setApplicationContext(context);
			}
			context.addApplicationListener(listener);
		}
		this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
	}

	@Override
	public void started(ConfigurableApplicationContext context, Duration timeTaken) {
		context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));
		AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
	}

	@Override
	public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
		context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context, timeTaken));
		AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
	}

	@Override
	public void failed(ConfigurableApplicationContext context, Throwable exception) {
		ApplicationFailedEvent event = new ApplicationFailedEvent(this.application, this.args, context, exception);
		if (context != null && context.isActive()) {
			// Listeners have been registered to the application context so we should
			// use it at this point if we can
			context.publishEvent(event);
		}
		else {
			// An inactive context may not have a multicaster so we use our multicaster to
			// call all of the context's listeners instead
			if (context instanceof AbstractApplicationContext) {
				for (ApplicationListener<?> listener : ((AbstractApplicationContext) context)
						.getApplicationListeners()) {
					this.initialMulticaster.addApplicationListener(listener);
				}
			}
			this.initialMulticaster.setErrorHandler(new LoggingErrorHandler());
			this.initialMulticaster.multicastEvent(event);
		}
	}

	private static class LoggingErrorHandler implements ErrorHandler {

		private static final Log logger = LogFactory.getLog(EventPublishingRunListener.class);

		@Override
		public void handleError(Throwable throwable) {
			logger.warn("Error calling ApplicationEventListener", throwable);
		}

	}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

我们在EventPublishingRunListener的构造方法中可以看到传入了SpringApplication,一个EventPublishingRunListener对应一个SpringApplication。而一个SpringApplication中包含多个监听器(Listeners)。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/609322
推荐阅读
相关标签
  

闽ICP备14008679号