源码分析:SpringBoot项目启动过程

6 篇文章 0 订阅

文章目录

前置准备

SpringBoot源码技术栈太过庞大,这里只是简版解读,后续会细化部分源码细节.

SpringApplication.run(…)

@SpringBootApplication
public class FactoryDemoApplication {

	public static void main(String[] args) {
        // 从Run开始Debug
		 SpringApplication.run(FactoryDemoApplication.class, args);
	}

}

创建SpringApplication

	public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
		return new SpringApplication(primarySources).run(args);
	}
	
	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		// 即传入的pringApplication.run传入的FactoryDemoApplication.class这个参数
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

推断上下文类型

通过WebApplicationType.deduceFromClasspath()实现的,其实就是判断指定类是不是存在。

 
 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;
	}

设置初始化参数

setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));

通过SpringFactoriesLoader.loadFactoryNames(加载工厂类

SpringFactoriesLoader.loadFactoryNames(type, classLoader)会加载全部并放入缓存中,方便后续使用。

"com.example.factory.project.ChildGenerationConfiguration" -> {LinkedList@1984}  size = 2
"org.springframework.boot.autoconfigure.EnableAutoConfiguration" -> {LinkedList@1985}  size = 128
"org.springframework.beans.BeanInfoFactory" -> {LinkedList@1986}  size = 1
"org.springframework.boot.env.EnvironmentPostProcessor" -> {LinkedList@2022}  size = 6
"org.springframework.context.ApplicationContextInitializer" -> {LinkedList@2024}  size = 8
"org.springframework.context.ApplicationListener" -> {LinkedList@2026}  size = 13
"org.springframework.boot.diagnostics.FailureAnalyzer" -> {LinkedList@2028}  size = 18
"org.springframework.boot.SpringApplicationRunListener" -> {LinkedList@2030}  size = 1
"org.springframework.boot.env.PropertySourceLoader" -> {LinkedList@2032}  size = 2
"org.springframework.boot.diagnostics.FailureAnalysisReporter" -> {LinkedList@2034}  size = 1
"org.springframework.boot.SpringBootExceptionReporter" -> {LinkedList@2036}  size = 1
"org.springframework.boot.autoconfigure.AutoConfigurationImportFilter" -> {LinkedList@2038}  size = 3
"org.springframework.boot.autoconfigure.AutoConfigurationImportListener" -> {LinkedList@2040}  size = 1
"org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider" -> {LinkedList@2042}  size = 5

获取ApplicationContextInitializer.class的对象

0 = "org.springframework.boot.devtools.restart.RestartScopeInitializer"
1 = "org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer"
2 = "org.springframework.boot.context.ContextIdApplicationContextInitializer"
3 = "org.springframework.boot.context.config.DelegatingApplicationContextInitializer"
4 = "org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer"
5 = "org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer"
6 = "org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer"
7 = "org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener"

实例化实现了ApplicationContextInitializer接口的所有对象并排序

通过AnnotationAwareOrderComparator.sort(instances);进行排序

0 = {DelegatingApplicationContextInitializer@1914} 
1 = {SharedMetadataReaderFactoryContextInitializer@1933} 
2 = {ContextIdApplicationContextInitializer@1896} 
3 = {RestartScopeInitializer@1861} 
4 = {ConfigurationWarningsApplicationContextInitializer@1878} 
5 = {RSocketPortInfoApplicationContextInitializer@1931} 
6 = {ServerPortInfoApplicationContextInitializer@1932} 
7 = {ConditionEvaluationReportLoggingListener@1934}

保存ApplicationContextInitializer

SpringApplication.setInitializers(Collection> initializers)

实例化监听器

获取ApplicationListener接口对象

0 = "org.springframework.boot.devtools.restart.RestartApplicationListener"
1 = "org.springframework.boot.devtools.logger.DevToolsLogFactory.Listener"
2 = "org.springframework.boot.ClearCachesApplicationListener"
3 = "org.springframework.boot.builder.ParentContextCloserApplicationListener"
4 = "org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor"
5 = "org.springframework.boot.context.FileEncodingApplicationListener"
6 = "org.springframework.boot.context.config.AnsiOutputApplicationListener"
7 = "org.springframework.boot.context.config.ConfigFileApplicationListener"
8 = "org.springframework.boot.context.config.DelegatingApplicationListener"
9 = "org.springframework.boot.context.logging.ClasspathLoggingApplicationListener"
10 = "org.springframework.boot.context.logging.LoggingApplicationListener"
11 = "org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener"
12 = "org.springframework.boot.autoconfigure.BackgroundPreinitializer"

使用DevTools 会添加DevToolsPropertyDefaultsPostProcessor

实例化并排序

0 = {RestartApplicationListener@2043} 
1 = {CloudFoundryVcapEnvironmentPostProcessor@2044} 
2 = {ConfigFileApplicationListener@2045} 
3 = {AnsiOutputApplicationListener@2046} 
4 = {LoggingApplicationListener@2047} 
5 = {ClasspathLoggingApplicationListener@2048} 
6 = {BackgroundPreinitializer@2049} 
7 = {DelegatingApplicationListener@2050} 
8 = {ParentContextCloserApplicationListener@2051} 
9 = {DevToolsLogFactory$Listener@2052} 
10 = {ClearCachesApplicationListener@2053} 
11 = {FileEncodingApplicationListener@2054} 
12 = {LiquibaseServiceLocatorApplicationListener@2055}

触发监听器

ConfigFileApplicationListener 处理配置文件

实现了EnvironmentPostProcessor接口,会依次加载DEFAULT_SEARCH_LOCATIONS 配置的路径下的配置文件到环境变量中。另外这里也添加了1个RandomValuePropertySource来解析随机数。

	private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/";
	
	
		private Set<String> getSearchLocations() {
			Set<String> locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY);
			if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) {
				locations.addAll(getSearchLocations(CONFIG_LOCATION_PROPERTY));
			}
			else {
				locations.addAll(
						asResolvedSet(ConfigFileApplicationListener.this.searchLocations, DEFAULT_SEARCH_LOCATIONS));
			}
			return locations;
		}
		
		private Set<String> asResolvedSet(String value, String fallback) {
			List<String> list = Arrays.asList(StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(
					(value != null) ? this.environment.resolvePlaceholders(value) : fallback)));
			Collections.reverse(list);
			return new LinkedHashSet<>(list);
		}

spring对路径字符串拆分后进行了翻转操作,所以这里的加载顺序为:

  • file:./config/
  • file:./config/*/
  • file:./
  • classpath:/config/
  • classpath:/

高优先级的会覆盖低优先级的配置属性。

解析配置文件名后使用不同的加载器进行加载配置文件,默认的配置文件解析器:

# 解析"properties", "xml"文件
0 = {PropertiesPropertySourceLoader@3449}  
# 解析 "yml", "yaml" 文件	
1 = {YamlPropertySourceLoader@3456} 	 	

解析到文件会以添加到上下文中

0 = {ConfigurationPropertySourcesPropertySource@2330} "ConfigurationPropertySourcesPropertySource {name='configurationProperties'}"
1 = {PropertySource$StubPropertySource@2331} "StubPropertySource {name='servletConfigInitParams'}"
2 = {PropertySource$StubPropertySource@2332} "StubPropertySource {name='servletContextInitParams'}"
3 = {PropertiesPropertySource@2333} "PropertiesPropertySource {name='systemProperties'}"
4 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@2702} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}"
5 = {RandomValuePropertySource@3191} "RandomValuePropertySource {name='random'}"
6 = {OriginTrackedMapPropertySource@4042} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.properties]'}"
7 = {OriginTrackedMapPropertySource@3962} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}"

保存ApplicationListener

SpringApplication.setListeners(Collection> listeners)

推断启动类

即获取main方法的所在类

try {
			StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
			for (StackTraceElement stackTraceElement : stackTrace) {
				if ("main".equals(stackTraceElement.getMethodName())) {
					return Class.forName(stackTraceElement.getClassName());
				}
			}
		}
		catch (ClassNotFoundException ex) {
			// Swallow and continue
		}
		return null;

启动

调用run方法

启动耗时监视

StopWatch stopWatch = new StopWatch();
		stopWatch.start();

配置headless

默认为true

private void configureHeadlessProperty() {
		System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
				System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
	}

配置SpringApplicationRunListeners

获取实现SpringApplicationRunListeners的工厂对象

0 = {EventPublishingRunListener@1958} 

将监听器放到SpringApplicationRunListeners中

实例化SpringApplicationRunListeners,并保存监听器

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

启动监听器

循环启动

目前只有一个监听器:EventPublishingRunListener

void starting() {
		for (SpringApplicationRunListener listener : this.listeners) {
			listener.starting();
		}
	}
EventPublishingRunListener触发广播ApplicationStartingEvent事件
	@Override
	public void starting() {
		this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
	}
获取支持ApplicationStartingEvent事件的所有监听器并缓存
0 = {LoggingApplicationListener@1805} 
1 = {BackgroundPreinitializer@1827} 
2 = {DelegatingApplicationListener@1828} 
3 = {LiquibaseServiceLocatorApplicationListener@1829} 
进行多播ApplicationStartingEvent

即循环调用支持ApplicationStartingEvent事件的监听器

for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			if (executor != null) {
				executor.execute(() -> invokeListener(listener, event));
			}
			else {
				invokeListener(listener, event);
			}
		}

配置入参

包装成DefaultApplicationArguments

	ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

准备环境变量

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
			ApplicationArguments applicationArguments) {
		// Create and configure the environment
		ConfigurableEnvironment environment = getOrCreateEnvironment();
		configureEnvironment(environment, applicationArguments.getSourceArgs());
		ConfigurationPropertySources.attach(environment);
		listeners.environmentPrepared(environment);
		bindToSpringApplication(environment);
		if (!this.isCustomEnvironment) {
			environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
					deduceEnvironmentClass());
		}
		ConfigurationPropertySources.attach(environment);
		return environment;
	}

根据环境创建环境变量

private ConfigurableEnvironment getOrCreateEnvironment() {
		if (this.environment != null) {
			return this.environment;
		}
		switch (this.webApplicationType) {
		case SERVLET:
			return new StandardServletEnvironment();
		case REACTIVE:
			return new StandardReactiveWebEnvironment();
		default:
			return new StandardEnvironment();
		}
	}

配置单例的ConversionService

	public static ConversionService getSharedInstance() {
		ApplicationConversionService sharedInstance = ApplicationConversionService.sharedInstance;
		if (sharedInstance == null) {
			synchronized (ApplicationConversionService.class) {
				sharedInstance = ApplicationConversionService.sharedInstance;
				if (sharedInstance == null) {
					sharedInstance = new ApplicationConversionService();
					ApplicationConversionService.sharedInstance = sharedInstance;
				}
			}
		}
		return sharedInstance;
	}

配置Properties参数

protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
		MutablePropertySources sources = environment.getPropertySources();
		if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) {
			sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties));
		}
		if (this.addCommandLineProperties && args.length > 0) {
			String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
			if (sources.contains(name)) {
				PropertySource<?> source = sources.get(name);
				CompositePropertySource composite = new CompositePropertySource(name);
				composite.addPropertySource(
						new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
				composite.addPropertySource(source);
				sources.replace(name, composite);
			}
			else {
				sources.addFirst(new SimpleCommandLinePropertySource(args));
			}
		}
	}

配置Profile

protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
		Set<String> profiles = new LinkedHashSet<>(this.additionalProfiles);
		profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
		environment.setActiveProfiles(StringUtils.toStringArray(profiles));
	}

附加额外参数

public static void attach(Environment environment) {
		Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
		MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();
		PropertySource<?> attached = sources.get(ATTACHED_PROPERTY_SOURCE_NAME);
		if (attached != null && attached.getSource() != sources) {
			sources.remove(ATTACHED_PROPERTY_SOURCE_NAME);
			attached = null;
		}
		if (attached == null) {
			sources.addFirst(new ConfigurationPropertySourcesPropertySource(ATTACHED_PROPERTY_SOURCE_NAME,
					new SpringConfigurationPropertySources(sources)));
		}
	}

触发ApplicationEnvironmentPreparedEvent广播事件

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

获取所有监听此事件的监听器

0 = {ConfigFileApplicationListener@2838} 
1 = {AnsiOutputApplicationListener@3747} 
2 = {LoggingApplicationListener@1805} 
3 = {ClasspathLoggingApplicationListener@3748} 
4 = {BackgroundPreinitializer@1827} 
5 = {DelegatingApplicationListener@1828} 
6 = {FileEncodingApplicationListener@3749} 

循环调用监听此事件的监听器,和前面解析步骤一致

@Override
	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		Executor executor = getTaskExecutor();
		for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			if (executor != null) {
				executor.execute(() -> invokeListener(listener, event));
			}
			else {
				invokeListener(listener, event);
			}
		}
	}

监听器

ConfigFileApplicationListener
  • 加载工厂类
0 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor@2911} 
1 = {SpringApplicationJsonEnvironmentPostProcessor@2912} 
2 = {CloudFoundryVcapEnvironmentPostProcessor@2913} 
3 = {ConfigFileApplicationListener@2838} 
4 = {DebugAgentEnvironmentPostProcessor@2914} 

创建Binder,绑定环境变量和SpringApplication

protected void bindToSpringApplication(ConfigurableEnvironment environment) {
		try {
			Binder.get(environment).bind("spring.main", Bindable.ofInstance(this));
		}
		catch (Exception ex) {
			throw new IllegalStateException("Cannot bind to SpringApplication", ex);
		}
	}
解析已存在的环境变量

封装结果保存在PropertySourcesPlaceholdersResolver

sources = {SpringConfigurationPropertySources@3220} 
 sources = {MutablePropertySources@3206} "[ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, StubPropertySource {name='servletConfigInitParams'}, StubPropertySource {name='servletContextInitParams'}, PropertiesPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}]"
  propertySourceList = {CopyOnWriteArrayList@3241}  size = 7
   0 = {ConfigurationPropertySourcesPropertySource@3212} "ConfigurationPropertySourcesPropertySource {name='configurationProperties'}"
   1 = {PropertySource$StubPropertySource@3243} "StubPropertySource {name='servletConfigInitParams'}"
   2 = {PropertySource$StubPropertySource@3244} "StubPropertySource {name='servletContextInitParams'}"
   3 = {PropertiesPropertySource@3245} "PropertiesPropertySource {name='systemProperties'}"
   4 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@3246} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}"
   5 = {RandomValuePropertySource@3247} "RandomValuePropertySource {name='random'}"
   6 = {OriginTrackedMapPropertySource@3248} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}"
 cache = {ConcurrentReferenceHashMap@3308}  size = 4
  {RandomValuePropertySource@3247} "RandomValuePropertySource {name='random'}" -> {SpringConfigurationPropertySource@3318} "RandomValuePropertySource {name='random'}"
  {SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@3246} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}" -> {SpringIterableConfigurationPropertySource@3319} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}"
  {PropertiesPropertySource@3245} "PropertiesPropertySource {name='systemProperties'}" -> {SpringIterableConfigurationPropertySource@3320} "PropertiesPropertySource {name='systemProperties'}"
  {OriginTrackedMapPropertySource@3248} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}" -> {SpringIterableConfigurationPropertySource@3321} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}"
绑定
protected void bindToSpringApplication(ConfigurableEnvironment environment) {
		try {
			Binder.get(environment).bind("spring.main", Bindable.ofInstance(this));
		}
		catch (Exception ex) {
			throw new IllegalStateException("Cannot bind to SpringApplication", ex);
		}
	}
重新设置"configurationProperties"
0 = {ConfigurationPropertySourcesPropertySource@3492} "ConfigurationPropertySourcesPropertySource {name='configurationProperties'}"
 logger = {LogAdapter$Slf4jLocationAwareLog@3505} 
 name = "configurationProperties"
 source = {SpringConfigurationPropertySources@3493} 
  sources = {MutablePropertySources@3402} "[ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, StubPropertySource {name='servletConfigInitParams'}, StubPropertySource {name='servletContextInitParams'}, PropertiesPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}]"
   propertySourceList = {CopyOnWriteArrayList@3406}  size = 7
    0 = {ConfigurationPropertySourcesPropertySource@3492} "ConfigurationPropertySourcesPropertySource {name='configurationProperties'}"
    1 = {PropertySource$StubPropertySource@3409} "StubPropertySource {name='servletConfigInitParams'}"
    2 = {PropertySource$StubPropertySource@3410} "StubPropertySource {name='servletContextInitParams'}"
    3 = {PropertiesPropertySource@3411} "PropertiesPropertySource {name='systemProperties'}"
    4 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@3412} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}"
    5 = {RandomValuePropertySource@3413} "RandomValuePropertySource {name='random'}"
    6 = {OriginTrackedMapPropertySource@3414} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}"
  cache = {ConcurrentReferenceHashMap@3494}  size = 0
1 = {PropertySource$StubPropertySource@3409} "StubPropertySource {name='servletConfigInitParams'}"
2 = {PropertySource$StubPropertySource@3410} "StubPropertySource {name='servletContextInitParams'}"
3 = {PropertiesPropertySource@3411} "PropertiesPropertySource {name='systemProperties'}"
4 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@3412} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}"
5 = {RandomValuePropertySource@3413} "RandomValuePropertySource {name='random'}"
6 = {OriginTrackedMapPropertySource@3414} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}"

配置忽略Bean信息

	private void configureIgnoreBeanInfo(ConfigurableEnvironment environment) {
		if (System.getProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME) == null) {
			Boolean ignore = environment.getProperty("spring.beaninfo.ignore", Boolean.class, Boolean.TRUE);
			System.setProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME, ignore.toString());
		}
	}

打印Banner

private Banner printBanner(ConfigurableEnvironment environment) {
		if (this.bannerMode == Banner.Mode.OFF) {
			return null;
		}
		ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader
				: new DefaultResourceLoader(getClassLoader());
		SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner);
		if (this.bannerMode == Mode.LOG) {
			return bannerPrinter.print(environment, this.mainApplicationClass, logger);
		}
		return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
	}
默认的Banner:SpringBootBanner
	public void printBanner(Environment environment, Class<?> sourceClass, PrintStream printStream) {
		for (String line : BANNER) {
			printStream.println(line);
		}
		String version = SpringBootVersion.getVersion();
		version = (version != null) ? " (v" + version + ")" : "";
		StringBuilder padding = new StringBuilder();
		while (padding.length() < STRAP_LINE_SIZE - (version.length() + SPRING_BOOT.length())) {
			padding.append(" ");
		}

		printStream.println(AnsiOutput.toString(AnsiColor.GREEN, SPRING_BOOT, AnsiColor.DEFAULT, padding.toString(),
				AnsiStyle.FAINT, version));
		printStream.println();
	}

创建上下文

根据类型实例化上下文

WEB默认情况下是AnnotationConfigServletWebServerApplicationContext,然后实例化。

protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
				switch (this.webApplicationType) {
				case SERVLET:
					contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
					break;
				case REACTIVE:
					contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
					break;
				default:
					contextClass = Class.forName("org.springframework.context."
			+ "annotation.AnnotationConfigApplicationContext");
				}
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
			}
		}
		return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
	}
  • 父类通用上下文:GenericApplicationContext

这里会实例化DefaultListableBeanFactory并保存在beanFactory属性中,后续都会基于它进行操作

public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}

简略版继承关系:

AnnotationConfigServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
GenericWebApplicationContext (org.springframework.web.context.support)
GenericApplicationContext (org.springframework.context.support)

  • 实例化AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		this(registry, getOrCreateEnvironment(registry));
	}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
  • 注册AnnotationConfigProcessors
		// 获取上下文,即上文提到的GenericApplicationContext#beanFactory

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				// Order比较器
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				// 自动转入
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		
		// org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			// @Configuration类的引导处理的BeanFactoryPostProcessor
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		// org.springframework.context.annotation.internalAutowiredAnnotationProcessor
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			// @Autowired @Value @Inject 等自动注入相关注解的处理类
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// org.springframework.context.annotation.internalCommonAnnotationProcessor
		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			// 支持普通的Java开箱即用注释,也支持JSR-250注释
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// jpa 功能支持 PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		
		// org.springframework.context.event.internalEventListenerProcessor
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            // 事件监听器
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}
		// org.springframework.context.event.internalEventListenerFactory
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			// 事件监听工厂
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

  • 实例化类扫描器ClassPathBeanDefinitionScanner

一个bean定义扫描器,它检测类路径上的bean候选,在给定的注册表(BeanFactory或ApplicationContext)中注册相应的bean定义,通过可配置的类型筛选器检测候选类,Bean条件过滤在这里做的。

 * {@link org.springframework.stereotype.Component @Component},
 * {@link org.springframework.stereotype.Repository @Repository},
 * {@link org.springframework.stereotype.Service @Service}, or
 * {@link org.springframework.stereotype.Controller @Controller} stereotype.
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
    this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
    this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
  • 添加默认过滤器
protected void registerDefaultFilters() {
		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
			logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
		}
		try {
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
			logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

获取SpringFactory实例SpringBootExceptionReporter

获取所有SpringBootExceptionReporter对象并实例化

用于触发从spring.factories加载的FailureAnalyzer和FailureAnalysisReporter实例的实用程序。 需要访问BeanFactory来执行分析的故障分析器可以实现BeanFactoryAware,以便在调用故障分析器.analyze(Throwable)之前注入BeanFactory

org.springframework.boot.diagnostics.FailureAnalyzers

准备上下文

把之前加载的监听器,启动参数,环境变量放到上下文中

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
		context.setEnvironment(environment);
		postProcessApplicationContext(context);
		applyInitializers(context);
		listeners.contextPrepared(context);
		if (this.logStartupInfo) {
			logStartupInfo(context.getParent() == null);
			logStartupProfileInfo(context);
		}
		// Add boot specific singleton beans
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
		if (printedBanner != null) {
			beanFactory.registerSingleton("springBootBanner", printedBanner);
		}
		if (beanFactory instanceof DefaultListableBeanFactory) {
			((DefaultListableBeanFactory) beanFactory)
					.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.lazyInitialization) {
			context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
		}
		// Load the sources
		Set<Object> sources = getAllSources();
		Assert.notEmpty(sources, "Sources must not be empty");
		load(context, sources.toArray(new Object[0]));
		listeners.contextLoaded(context);
	}
应用初始化
  • 获取之前的Initializer对象
0 = {DelegatingApplicationContextInitializer@3540} 
1 = {SharedMetadataReaderFactoryContextInitializer@3541} 
2 = {ContextIdApplicationContextInitializer@3542} 
3 = {ConfigurationWarningsApplicationContextInitializer@3543} 
4 = {RSocketPortInfoApplicationContextInitializer@3544} 
5 = {ServerPortInfoApplicationContextInitializer@3545} 
6 = {ConditionEvaluationReportLoggingListener@3546} 
  • Initializer如果实现了ApplicationContextInitializer接口,那么回调设置上下文
protected void applyInitializers(ConfigurableApplicationContext context) {
		for (ApplicationContextInitializer initializer : getInitializers()) {
			Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
					ApplicationContextInitializer.class);
			Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
			initializer.initialize(context);
		}
	}
触发contextPrepared事件ApplicationContextInitializedEvent

监听该事件的监听器

0 = {BackgroundPreinitializer@3824} 
1 = {DelegatingApplicationListener@3831} 
打印启动信息
new StartupInfoLogger(this.mainApplicationClass).logStarting(getApplicationLog());

void logStarting(Log applicationLog) {
		Assert.notNull(applicationLog, "Log must not be null");
		applicationLog.info(LogMessage.of(this::getStartingMessage));
		applicationLog.debug(LogMessage.of(this::getRunningMessage));
	}
private CharSequence getStartingMessage() {
    StringBuilder message = new StringBuilder();
    message.append("Starting ");
    appendApplicationName(message);
    appendVersion(message, this.sourceClass);
    appendOn(message);
    appendPid(message);
    appendContext(message);
    return message;
}

StartingMessage: info

2020-04-16 11:22:38.085  INFO 17884 --- [           main] c.e.factory.app.FactoryDemoApplication   : Starting FactoryDemoApplication on Ccx with PID 17884 (E:\IDEA\ccxxx\factory-demo\target\classes started by cx521 in E:\IDEA\ccxxx)

RunningMessage: debug

2020-04-16 11:26:52.314 DEBUG 17884 --- [           main] c.e.factory.app.FactoryDemoApplication   : Running with Spring Boot v2.2.2.RELEASE, Spring v5.2.2.RELEASE

打印当前环境:

protected void logStartupProfileInfo(ConfigurableApplicationContext context) {
		Log log = getApplicationLog();
		if (log.isInfoEnabled()) {
			String[] activeProfiles = context.getEnvironment().getActiveProfiles();
			if (ObjectUtils.isEmpty(activeProfiles)) {
				String[] defaultProfiles = context.getEnvironment().getDefaultProfiles();
				log.info("No active profile set, falling back to default profiles: "
						+ StringUtils.arrayToCommaDelimitedString(defaultProfiles));
			}
			else {
				log.info("The following profiles are active: "
						+ StringUtils.arrayToCommaDelimitedString(activeProfiles));
			}
		}
	}
2020-04-16 11:28:14.143  INFO 17884 --- [           main] c.e.factory.app.FactoryDemoApplication   : No active profile set, falling back to default profiles: default

添加一些额外的Bean支持
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
    beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
    ((DefaultListableBeanFactory) beanFactory)
    .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.lazyInitialization) {
    context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
设置BeanDefinitionLoader
  • 设置各种资源加载器
	BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {
		Assert.notNull(registry, "Registry must not be null");
		Assert.notEmpty(sources, "Sources must not be empty");
		this.sources = sources;
		this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);
		this.xmlReader = new XmlBeanDefinitionReader(registry);
		if (isGroovyPresent()) {
			this.groovyReader = new GroovyBeanDefinitionReader(registry);
		}
		this.scanner = new ClassPathBeanDefinitionScanner(registry);
		this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
	}
  • 调用load方法进行加载
// sources为启动类
protected void load(ApplicationContext context, Object[] sources) {
		if (logger.isDebugEnabled()) {
			logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
		}
		BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
		if (this.beanNameGenerator != null) {
			loader.setBeanNameGenerator(this.beanNameGenerator);
		}
		if (this.resourceLoader != null) {
			loader.setResourceLoader(this.resourceLoader);
		}
		if (this.environment != null) {
			loader.setEnvironment(this.environment);
		}
		loader.load();
	}
触发contextLoaded事件
  • 获取所有监听事件
0 = {CloudFoundryVcapEnvironmentPostProcessor@4378} 
1 = {ConfigFileApplicationListener@3859} 
2 = {AnsiOutputApplicationListener@3860} 
3 = {LoggingApplicationListener@3861} 
4 = {ClasspathLoggingApplicationListener@3862} 
5 = {BackgroundPreinitializer@3824} 
6 = {DelegatingApplicationListener@3831} 
7 = {ParentContextCloserApplicationListener@4379} 
8 = {ClearCachesApplicationListener@4380} 
9 = {FileEncodingApplicationListener@3863} 
10 = {LiquibaseServiceLocatorApplicationListener@4381} 
  • 将监听器添加到上下文中,如果实现了ApplicationContextAware接口的会进行上下文回调。
	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));
	}
触发ApplicationPreparedEvent事件

进行数据回调

0 = {CloudFoundryVcapEnvironmentPostProcessor@3657} 
1 = {ConfigFileApplicationListener@3675} 
2 = {LoggingApplicationListener@3676} 
3 = {BackgroundPreinitializer@3365} 
4 = {DelegatingApplicationListener@3381} 

刷新上下文

spring的标准流程,spring启动

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}
准备刷新 prepareRefresh

清空缓存,这里有2个回调,模板方法都是空实现

	protected void prepareRefresh() {
		// Switch to active.
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

earlyApplicationListeners列表

0 = {RSocketPortInfoApplicationContextInitializer$Listener@3716} 
1 = {ServerPortInfoApplicationContextInitializer@3717} 
2 = {ConditionEvaluationReportLoggingListener$ConditionEvaluationReportListener@3718} 
3 = {CloudFoundryVcapEnvironmentPostProcessor@3719} 
4 = {ConfigFileApplicationListener@3720} 
5 = {AnsiOutputApplicationListener@3721} 
6 = {LoggingApplicationListener@3722} 
7 = {ClasspathLoggingApplicationListener@3723} 
8 = {BackgroundPreinitializer@3724} 
9 = {DelegatingApplicationListener@3725} 
10 = {ParentContextCloserApplicationListener@3726} 
11 = {ClearCachesApplicationListener@3727} 
12 = {FileEncodingApplicationListener@3728} 
13 = {LiquibaseServiceLocatorApplicationListener@3729} 
获取工厂obtainFreshBeanFactory

调用GenericApplicationContext获取BeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}
准备一些初始化信息prepareBeanFactory
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
        // BeanExpressionResolver接口的标准实现,Spring EL解析,ex: #{beanName}
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        //填充给定PropertyEditorRegistry(通常是org.springframe .bean)的PropertyEditorRegistry实现。
        //用于在带有资源编辑器的org.springframework.context. context中创建bean的BeanWrapper。
        //由org.springframework.context.support.AbstractApplicationContext使用
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 配置工厂回调
        // BeanPostProcessor实现供应ApplicationContext,环境,或StringValueResolver 
        //ApplicationContext EnvironmentAware bean实现,EmbeddedValueResolverAware, ResourceLoaderAware, 
        // ApplicationEventPublisherAware MessageSourceAware和/或ApplicationContextAware接口。 
        //实现的接口按照上面提到的顺序被满足。 应用程序上下文将自动将其注册到它们的底层bean工厂。应用程序不直接使用它。
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        // 忽略给定的自动装配依赖接口,由系统自动调用
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// 将系统Bean加入到容器中,我们可以在系统通过注入的方式获取
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// 将早期的后处理器注册为application监听器,用于检测内部bean。
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 注册环境变量相关Bean
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}
		
调用工厂中的处理器

Spiring 将BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor区分开调用:

BeanDefinitionRegistryPostProcessor实现自BeanFactoryPostProcessor,因此需要2步:

1.void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

2.void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

单独BeanFactoryPostProcessor接口:

1.void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}
  • 先处理内部的BeanFactoryPostProcessor,保存在AbstractApplicationContext.beanFactoryPostProcessors中:
0 = {SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor@4139} 
1 = {ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor@4140} 
2 = {ConfigFileApplicationListener$PropertySourceOrderingPostProcessor@4141} 

BeanDefinitionRegistryPostProcessor 实现自 BeanFactoryPostProcessor接口,调用前需要先调用BeanDefinitionRegistryPostProcessor 的postProcessBeanDefinitionRegistry接口,

	for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}
  • 实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor:

currentRegistryProcessors保存从上下文中获取到实现PriorityOrdered接口的实例;

postProcessorNames保存的是beanName;

List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
Set<String> processedBeans = new HashSet<>();
String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				// 注意这里类型过滤为 PriorityOrdered.class
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 将容器中获取的processor添加到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
// 循环调用新加的processor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 清空临时列表
currentRegistryProcessors.clear();

循环调用新加的processor:

这里新加的是org.springframework.context.annotation.ConfigurationClassPostProcessor

private static void invokeBeanDefinitionRegistryPostProcessors(
      Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

   for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
      postProcessor.postProcessBeanDefinitionRegistry(registry);
   }
}
  • 实现Ordered接口的BeanFactoryPostProcessor:

currentRegistryProcessors保存从上下文中获取到实现Ordered接口的实例;

postProcessorNames保存的是beanName;

	postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				// 注意这里类型过滤为 Ordered.class,且postProcessorName不存在,防止重复调用
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
            // 排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 将容器中获取的processor添加到registryProcessors中
            registryProcessors.addAll(currentRegistryProcessors);
            // 循环调用新加的processor
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 清空临时列表
            currentRegistryProcessors.clear();
  • 处理剩下无序的processor:
boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					// postProcessorName不存在的,防止重复调用
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
  			// 排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 将容器中获取的processor添加到registryProcessors中
            registryProcessors.addAll(currentRegistryProcessors);
            // 循环调用新加的processor
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 清空临时列表
            currentRegistryProcessors.clear();
  • 调用postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)

    循环实现了BeanDefinitionRegistryPostProcessor接口的实例.

// 实现了BeanDefinitionRegistryPostProcessor的接口
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 只实现了BeanFactoryPostProcessor的接口
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

private static void invokeBeanFactoryPostProcessors(
      Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

   for (BeanFactoryPostProcessor postProcessor : postProcessors) {
      postProcessor.postProcessBeanFactory(beanFactory);
   }
}
  • 获取容器中只实现了BeanFactoryPostProcessors的处理器,注意和前边步骤BeanDefinitionRegistryPostProcessor区分开,前边是需要两步操作:

    1.void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

    2.void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			// 这里排除了已经处理过的processor
			if (processedBeans.contains(ppName)) {
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}
		
		// 首先调用实现了PriorityOrdered接口的
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 然后实现了Ordered接口的
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 调用无须的
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// 清空源信息
		beanFactory.clearMetadataCache();
初始化国际化
	protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			// 默认实现
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
			}
		}
	}
初始化事件广播器
protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
            // 默认的广播实例
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}
刷新
protected void onRefresh() {
    // 调用的是GenericWebApplicationContext.onRefresh();
   super.onRefresh();
   try {
       // 创建WebServer
      createWebServer();
   }
   catch (Throwable ex) {
      throw new ApplicationContextException("Unable to start web server", ex);
   }
}
// 是GenericWebApplicationContext.onRefresh
protected void onRefresh() {
    // 初始化主题
    this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}

创建Web服务(Tomcat启动)

调用ServletWebServerApplicationContext的createWebServer方法

private void createWebServer() {
		// 启动时为null
		WebServer webServer = this.webServer;
		// 启动时为null
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
			ServletWebServerFactory factory = getWebServerFactory();
			this.webServer = factory.getWebServer(getSelfInitializer());
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context", ex);
			}
		}
		initPropertySources();
	}
	
    protected ServletWebServerFactory getWebServerFactory() {
    // Use bean names so that we don't consider the hierarchy
    // 这里会获取到tomcatServletWebServerFactory
    String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
    if (beanNames.length == 0) {
    throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
    + "ServletWebServerFactory bean.");
    }
    if (beanNames.length > 1) {
    throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
    + "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
    }
    return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
    }
获取Tomcat 服务

TomcatServletWebServerFactory#getWebServer

public WebServer getWebServer(ServletContextInitializer... initializers) {
    	if (this.disableMBeanRegistry) {
            // 默认禁用MBean注册
			Registry.disableRegistry();
		}
		Tomcat tomcat = new Tomcat();
    	// 创建了一个临时目录,ex: C:\Users\cx521\AppData\Local\Temp\tomcat.5544330150298139628.8080
		File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
    	// 设置Tomcat基本路径
		tomcat.setBaseDir(baseDir.getAbsolutePath());
    	// 创建连接
		Connector connector = new Connector(this.protocol);
    	// 启动失败时抛出异常
		connector.setThrowOnFailure(true);
		tomcat.getService().addConnector(connector);
    	// 自定义连接信息
		customizeConnector(connector);
		tomcat.setConnector(connector);
    	// 自动部署
		tomcat.getHost().setAutoDeploy(false);
    	// 配置引擎
		configureEngine(tomcat.getEngine());
		for (Connector additionalConnector : this.additionalTomcatConnectors) {
			tomcat.getService().addConnector(additionalConnector);
		}
    	// 准备环境
		prepareContext(tomcat.getHost(), initializers);
    	// 启动在这里进行.new TomcatWebServer(tomcat, getPort() >= 0);
		return getTomcatWebServer(tomcat);
	}

// 临时目录名为tomcat.端口形式
protected final File createTempDir(String prefix) {
    File tempDir = File.createTempFile(prefix + ".", "." + getPort());
    tempDir.delete();
    tempDir.mkdir();
    tempDir.deleteOnExit();
    return tempDir;
}

// 自定义连接
protected void customizeConnector(Connector connector) {
    	// 设置端口
		int port = Math.max(getPort(), 0);
		connector.setPort(port);
		if (StringUtils.hasText(this.getServerHeader())) {
			connector.setAttribute("server", this.getServerHeader());
		}
		if (connector.getProtocolHandler() instanceof AbstractProtocol) {
            // 自定义协议
			customizeProtocol((AbstractProtocol<?>) connector.getProtocolHandler());
		}
    	// 自定义协议处理器,默认为Http11NioProtocol
		invokeProtocolHandlerCustomizers(connector.getProtocolHandler());
		if (getUriEncoding() != null) {
            // 设置编码为UTF-8
			connector.setURIEncoding(getUriEncoding().name());
		}
		// 延迟绑定
		connector.setProperty("bindOnInit", "false");
    	// 设置ssl,https相关
		if (getSsl() != null && getSsl().isEnabled()) {
			customizeSsl(connector);
		}
    	// 设置压缩,最小响应包大小为2048B
		TomcatConnectorCustomizer compression = new CompressionConnectorCustomizer(getCompression());
		compression.customize(connector);
    	// 添加 其他的自定义属性,比如TomcatWebServerFactoryCustomizer#customize中定义的
		for (TomcatConnectorCustomizer customizer : this.tomcatConnectorCustomizers) {
			customizer.customize(connector);
		}
	}

// 准备上下文
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
		File documentRoot = getValidDocumentRoot();
		TomcatEmbeddedContext context = new TomcatEmbeddedContext();
		if (documentRoot != null) {
			context.setResources(new LoaderHidingResourceRoot(context));
		}
    	// 设置名称
		context.setName(getContextPath());
    	// 名字
		context.setDisplayName(getDisplayName());
    	// 路径
		context.setPath(getContextPath());
    	// 创建文档路径, ex: C:\Users\cx521\AppData\Local\Temp\tomcat-docbase.4781687470030327872.8080
		File docBase = (documentRoot != null) ? documentRoot : createTempDir("tomcat-docbase");
		context.setDocBase(docBase.getAbsolutePath());
    	// 设置监听器 上下文中的start()方法将把“configured”设置为false,并期望侦听器将其设置回true
		context.addLifecycleListener(new FixContextListener());
    	// 类加载器
		context.setParentClassLoader((this.resourceLoader != null) ? this.resourceLoader.getClassLoader()
				: ClassUtils.getDefaultClassLoader());
    	// 重置默认的映射
		resetDefaultLocaleMapping(context);
    	// 添加本地映射,HttpEncodingAutoConfiguration会去设置
		addLocaleMappings(context);
		context.setUseRelativeRedirects(false);
		try {
			context.setCreateUploadTargets(true);
		}
		catch (NoSuchMethodError ex) {
			// Tomcat is < 8.5.39. Continue.
		}
    	// 配置跳过指定jar过滤器表达式
		configureTldSkipPatterns(context);
		WebappLoader loader = new WebappLoader(context.getParentClassLoader());
		loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
		loader.setDelegate(true);
		context.setLoader(loader);
    	// 添加默认的Servlet
		if (isRegisterDefaultServlet()) {
			addDefaultServlet(context);
		}
    	// 添加JspServlet
		if (shouldRegisterJspServlet()) {
			addJspServlet(context);
			addJasperInitializer(context);
		}
		context.addLifecycleListener(new StaticResourceConfigurer(context));
		ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
		host.addChild(context);
    	// 配置上下文
		configureContext(context, initializersToUse);
		postProcessContext(context);
	}

protected void configureContext(Context context, ServletContextInitializer[] initializers) {
		TomcatStarter starter = new TomcatStarter(initializers);
		if (context instanceof TomcatEmbeddedContext) {
            // 嵌入式上下文环境
			TomcatEmbeddedContext embeddedContext = (TomcatEmbeddedContext) context;
			embeddedContext.setStarter(starter);
			embeddedContext.setFailCtxIfServletStartFails(true);
		}
		context.addServletContainerInitializer(starter, NO_CLASSES);
		for (LifecycleListener lifecycleListener : this.contextLifecycleListeners) {
			context.addLifecycleListener(lifecycleListener);
		}
		for (Valve valve : this.contextValves) {
			context.getPipeline().addValve(valve);
		}
    	// 设置异常页面
		for (ErrorPage errorPage : getErrorPages()) {
			org.apache.tomcat.util.descriptor.web.ErrorPage tomcatErrorPage = new org.apache.tomcat.util.descriptor.web.ErrorPage();
			tomcatErrorPage.setLocation(errorPage.getPath());
			tomcatErrorPage.setErrorCode(errorPage.getStatusCode());
			tomcatErrorPage.setExceptionType(errorPage.getExceptionName());
			context.addErrorPage(tomcatErrorPage);
		}
    	// 设置mime映射
		for (MimeMappings.Mapping mapping : getMimeMappings()) {
			context.addMimeMapping(mapping.getExtension(), mapping.getMimeType());
		}
		configureSession(context);
		new DisableReferenceClearingContextCustomizer().customize(context);
		for (TomcatContextCustomizer customizer : this.tomcatContextCustomizers) {
			customizer.customize(context);
		}
	}

Http11NioProtocol的属性:

compressionConfig = {CompressionConfig@13417} 
 compressionLevel = 0
 noCompressionUserAgents = null
 compressibleMimeType = "text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json,application/xml"
 compressibleMimeTypes = null
 compressionMinSize = 2048
useKeepAliveResponseHeader = true
relaxedPathChars = null
relaxedQueryChars = null
allowHostHeaderMismatch = false
rejectIllegalHeaderName = true
maxSavePostSize = 4096
maxHttpHeaderSize = 8192
connectionUploadTimeout = 300000
disableUploadTimeout = true
restrictedUserAgents = null
server = null
serverRemoveAppProvidedValues = false
maxTrailerSize = 8192
maxExtensionSize = 8192
maxSwallowSize = 2097152
secure = false
allowedTrailerHeaders = {Collections$SetFromMap@13418}  size = 0
upgradeProtocols = {ArrayList@13419}  size = 0
httpUpgradeProtocols = {HashMap@13420}  size = 0
negotiatedProtocols = {HashMap@13421}  size = 0
defaultSSLHostConfig = null
rgOname = null
nameIndex = 1
endpoint = {NioEndpoint@13422} 
handler = {AbstractProtocol$ConnectionHandler@13423} 
 proto = {Http11NioProtocol@13347} 
 global = {RequestGroupInfo@13437} "BaseModelMbean[null]"
 registerCount = {AtomicLong@13438} "0"
 recycledProcessors = {AbstractProtocol$RecycledProcessors@13439} 
waitingProcessors = {Collections$SetFromMap@13424}  size = 0
timeoutFuture = null
monitorFuture = null
adapter = null
processorCache = 200
clientCertProvider = null
maxHeaderCount = 100
domain = null
oname = null
mserver = null

自定义的属性TomcatWebServerFactoryCustomizer#customize

	@Override
	public void customize(ConfigurableTomcatWebServerFactory factory) {
		ServerProperties properties = this.serverProperties;
		ServerProperties.Tomcat tomcatProperties = properties.getTomcat();
		PropertyMapper propertyMapper = PropertyMapper.get();
		propertyMapper.from(tomcatProperties::getBasedir).whenNonNull().to(factory::setBaseDirectory);
		propertyMapper.from(tomcatProperties::getBackgroundProcessorDelay).whenNonNull().as(Duration::getSeconds)
				.as(Long::intValue).to(factory::setBackgroundProcessorDelay);
		customizeRemoteIpValve(factory);
		propertyMapper.from(tomcatProperties::getMaxThreads).when(this::isPositive)
				.to((maxThreads) -> customizeMaxThreads(factory, tomcatProperties.getMaxThreads()));
		propertyMapper.from(tomcatProperties::getMinSpareThreads).when(this::isPositive)
				.to((minSpareThreads) -> customizeMinThreads(factory, minSpareThreads));
		propertyMapper.from(this::determineMaxHttpHeaderSize).whenNonNull().asInt(DataSize::toBytes)
				.when(this::isPositive)
				.to((maxHttpHeaderSize) -> customizeMaxHttpHeaderSize(factory, maxHttpHeaderSize));
		propertyMapper.from(tomcatProperties::getMaxSwallowSize).whenNonNull().asInt(DataSize::toBytes)
				.to((maxSwallowSize) -> customizeMaxSwallowSize(factory, maxSwallowSize));
		propertyMapper.from(tomcatProperties::getMaxHttpPostSize).asInt(DataSize::toBytes)
				.when((maxHttpPostSize) -> maxHttpPostSize != 0)
				.to((maxHttpPostSize) -> customizeMaxHttpPostSize(factory, maxHttpPostSize));
		propertyMapper.from(tomcatProperties::getAccesslog).when(ServerProperties.Tomcat.Accesslog::isEnabled)
				.to((enabled) -> customizeAccessLog(factory));
		propertyMapper.from(tomcatProperties::getUriEncoding).whenNonNull().to(factory::setUriEncoding);
		propertyMapper.from(properties::getConnectionTimeout).whenNonNull()
				.to((connectionTimeout) -> customizeConnectionTimeout(factory, connectionTimeout));
		propertyMapper.from(tomcatProperties::getMaxConnections).when(this::isPositive)
				.to((maxConnections) -> customizeMaxConnections(factory, maxConnections));
		propertyMapper.from(tomcatProperties::getAcceptCount).when(this::isPositive)
				.to((acceptCount) -> customizeAcceptCount(factory, acceptCount));
		customizeStaticResources(factory);
		customizeErrorReportValve(properties.getError(), factory);
	}

跳过指定jar

0 = "ant-*.jar"
1 = "aspectj*.jar"
2 = "commons-beanutils*.jar"
3 = "commons-codec*.jar"
4 = "commons-collections*.jar"
5 = "commons-dbcp*.jar"
6 = "commons-digester*.jar"
7 = "commons-fileupload*.jar"
8 = "commons-httpclient*.jar"
9 = "commons-io*.jar"
10 = "commons-lang*.jar"
11 = "commons-logging*.jar"
12 = "commons-math*.jar"
13 = "commons-pool*.jar"
14 = "geronimo-spec-jaxrpc*.jar"
15 = "h2*.jar"
16 = "hamcrest*.jar"
17 = "hibernate*.jar"
18 = "jaxb-runtime-*.jar"
19 = "jmx*.jar"
20 = "jmx-tools-*.jar"
21 = "jta*.jar"
22 = "junit-*.jar"
23 = "httpclient*.jar"
24 = "log4j-*.jar"
25 = "mail*.jar"
26 = "org.hamcrest*.jar"
27 = "slf4j*.jar"
28 = "tomcat-embed-core-*.jar"
29 = "tomcat-embed-logging-*.jar"
30 = "tomcat-jdbc-*.jar"
31 = "tomcat-juli-*.jar"
32 = "tools.jar"
33 = "wsdl4j*.jar"
34 = "xercesImpl-*.jar"
35 = "xmlParserAPIs-*.jar"
36 = "xml-apis-*.jar"
37 = "antlr-*.jar"
38 = "aopalliance-*.jar"
39 = "aspectjrt-*.jar"
40 = "aspectjweaver-*.jar"
41 = "classmate-*.jar"
42 = "dom4j-*.jar"
43 = "ecj-*.jar"
44 = "ehcache-core-*.jar"
45 = "hibernate-core-*.jar"
46 = "hibernate-commons-annotations-*.jar"
47 = "hibernate-entitymanager-*.jar"
48 = "hibernate-jpa-2.1-api-*.jar"
49 = "hibernate-validator-*.jar"
50 = "hsqldb-*.jar"
51 = "jackson-annotations-*.jar"
52 = "jackson-core-*.jar"
53 = "jackson-databind-*.jar"
54 = "jandex-*.jar"
55 = "javassist-*.jar"
56 = "jboss-logging-*.jar"
57 = "jboss-transaction-api_*.jar"
58 = "jcl-over-slf4j-*.jar"
59 = "jdom-*.jar"
60 = "jul-to-slf4j-*.jar"
61 = "log4j-over-slf4j-*.jar"
62 = "logback-classic-*.jar"
63 = "logback-core-*.jar"
64 = "rome-*.jar"
65 = "slf4j-api-*.jar"
66 = "spring-aop-*.jar"
67 = "spring-aspects-*.jar"
68 = "spring-beans-*.jar"
69 = "spring-boot-*.jar"
70 = "spring-core-*.jar"
71 = "spring-context-*.jar"
72 = "spring-data-*.jar"
73 = "spring-expression-*.jar"
74 = "spring-jdbc-*.jar,"
75 = "spring-orm-*.jar"
76 = "spring-oxm-*.jar"
77 = "spring-tx-*.jar"
78 = "snakeyaml-*.jar"
79 = "tomcat-embed-el-*.jar"
80 = "validation-api-*.jar"
启动Tomcat(TomcatWebServer#initialize)
	private void initialize() throws WebServerException {
		logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
		synchronized (this.monitor) {
			try {
				addInstanceIdToEngineName();
				// StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]
				Context context = findContext();
				context.addLifecycleListener((event) -> {
					if (context.equals(event.getSource()) && Lifecycle.START_EVENT.equals(event.getType())) {
						// Remove service connectors so that protocol binding doesn't
						// happen when the service is started.
						removeServiceConnectors();
					}
				});

				// 启动服务器以触发初始化监听器
				this.tomcat.start();

				// We can re-throw failure exception directly in the main thread
				rethrowDeferredStartupExceptions();

				try {
					ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
				}
				catch (NamingException ex) {
					// Naming is not enabled. Continue
				}

				// Unlike Jetty, all Tomcat threads are daemon threads. We create a
				// blocking non-daemon to stop immediate shutdown
				startDaemonAwaitThread();
			}
			catch (Exception ex) {
				stopSilently();
				destroySilently();
				throw new WebServerException("Unable to start embedded Tomcat", ex);
			}
		}
	}
初始化资源
@Override
	public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
		WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
	}
注册监听器
  • 存放在SimpleApplicationEventMulticaster#defaultRetriever
protected void registerListeners() {
		// 首先注册静态指定的侦听器。
		for (ApplicationListener<?> listener : getApplicationListeners()) {
            // 工厂自带的监听器需要检查下是否被代理,有的话需要去除
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

	}

public void addApplicationListener(ApplicationListener<?> listener) {
		synchronized (this.retrievalMutex) {
			// 如果已经注册,则显式删除代理的目标,以避免对同一侦听器的重复调用。
			Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
			if (singletonTarget instanceof ApplicationListener) {
				// 删除
				this.defaultRetriever.applicationListeners.remove(singletonTarget);
			}
			this.defaultRetriever.applicationListeners.add(listener);
			this.retrieverCache.clear();
		}
	}

工厂中自带的ApplicationListener

0 = {RSocketPortInfoApplicationContextInitializer$Listener@29269} 
1 = {ServerPortInfoApplicationContextInitializer@29398} 
2 = {ConditionEvaluationReportLoggingListener$ConditionEvaluationReportListener@29399} 
3 = {CloudFoundryVcapEnvironmentPostProcessor@29400} 
4 = {ConfigFileApplicationListener@29401} 
5 = {AnsiOutputApplicationListener@29402} 
6 = {LoggingApplicationListener@29403} 
7 = {ClasspathLoggingApplicationListener@29404} 
8 = {BackgroundPreinitializer@29405} 
9 = {DelegatingApplicationListener@29406} 
10 = {ParentContextCloserApplicationListener@29407} 
11 = {ClearCachesApplicationListener@29408} 
12 = {FileEncodingApplicationListener@29409} 
13 = {LiquibaseServiceLocatorApplicationListener@29410} 
14 = {SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean@12087} 
  • 获取容器注册的监听器
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			// 直接添加
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}
		
public void addApplicationListenerBean(String listenerBeanName) {
		synchronized (this.retrievalMutex) {
			this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
			this.retrieverCache.clear();
		}
	}
  • 获取早期的应用事件

    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    		this.earlyApplicationEvents = null;
    		if (earlyEventsToProcess != null) {
    			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
    				getApplicationEventMulticaster().multicastEvent(earlyEvent);
    			}
    		}
    
完成工厂初始化finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 为此上下文初始化转换服务。
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// 设置冻结,允许缓存所有的bean定义元数据。
		beanFactory.freezeConfiguration();

		// 实例化所有非延迟加载的单例对象
		beanFactory.preInstantiateSingletons();
	}
完成刷新 finishRefresh

ServletWebServerApplicationContext#finishRefresh

@Override
	protected void finishRefresh() {
		super.finishRefresh();
		WebServer webServer = startWebServer();
		if (webServer != null) {
			publishEvent(new ServletWebServerInitializedEvent(webServer, this));
		}
	}
调用父类AbstractApplicationContext#finishRefresh
protected void finishRefresh() {
		// 清除上下文级的资源缓存(比如扫描的ASM元数据)。
		clearResourceCaches();

		// 为此上下文初始化生命周期处理器。DefaultLifecycleProcessor
		initLifecycleProcessor();

		// 生命周期处理器开始运行.
		getLifecycleProcessor().onRefresh();

		// 推送PayloadApplicationEvent事件	
		publishEvent(new ContextRefreshedEvent(this));

		//注册MBean.
		LiveBeansView.registerApplicationContext(this);
	}
发送ServletWebServerInitializedEvent事件
0 = {SpringApplicationAdminMXBeanRegistrar@30505} 
1 = {DelegatingApplicationListener@29406} 
2 = {ServerPortInfoApplicationContextInitializer@29398} 
清空元数据缓存resetCommonCaches
	protected void resetCommonCaches() {
		ReflectionUtils.clearCache();
		AnnotationUtils.clearCache();
		ResolvableType.clearCache();
		CachedIntrospectionResults.clearClassLoader(getClassLoader());
	}
注册个关闭的勾子

在虚拟中注册个勾子,以供关闭时能调用生命周期方法

public void registerShutdownHook() {
		if (this.shutdownHook == null) {
			// No shutdown hook registered yet.
			this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
				@Override
				public void run() {
					synchronized (startupShutdownMonitor) {
						doClose();
					}
				}
			};
			Runtime.getRuntime().addShutdownHook(this.shutdownHook);
		}
	}
	
	
	protected void doClose() {
		// Check whether an actual close attempt is necessary...
		if (this.active.get() && this.closed.compareAndSet(false, true)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Closing " + this);
			}

			LiveBeansView.unregisterApplicationContext(this);

			try {
				// Publish shutdown event.
				publishEvent(new ContextClosedEvent(this));
			}
			catch (Throwable ex) {
				logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
			}

			// Stop all Lifecycle beans, to avoid delays during individual destruction.
			if (this.lifecycleProcessor != null) {
				try {
					this.lifecycleProcessor.onClose();
				}
				catch (Throwable ex) {
					logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
				}
			}

			// Destroy all cached singletons in the context's BeanFactory.
			destroyBeans();

			// Close the state of this context itself.
			closeBeanFactory();

			// Let subclasses do some final clean-up if they wish...
			onClose();

			// Reset local application listeners to pre-refresh state.
			if (this.earlyApplicationListeners != null) {
				this.applicationListeners.clear();
				this.applicationListeners.addAll(this.earlyApplicationListeners);
			}

			// Switch to inactive.
			this.active.set(false);
		}
	}

模板方法afterRefresh

不做任何实现

protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {
	}

关闭监视器,打印启动耗时

2020-04-16 19:34:40.634  INFO 9204 --- [           main] c.e.factory.app.FactoryDemoApplication   : Started FactoryDemoApplication in 211.377 seconds (JVM running for 212.963)

推送应用启动事件ApplicationStartedEvent

0 = {BackgroundPreinitializer@29405} 
1 = {DelegatingApplicationListener@29406} 

回调实现了ApplicationRunner和CommandLineRunner接口的实例

private void callRunners(ApplicationContext context, ApplicationArguments args) {
		List<Object> runners = new ArrayList<>();
		runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
		runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
		AnnotationAwareOrderComparator.sort(runners);
		for (Object runner : new LinkedHashSet<>(runners)) {
			if (runner instanceof ApplicationRunner) {
				callRunner((ApplicationRunner) runner, args);
			}
			if (runner instanceof CommandLineRunner) {
				callRunner((CommandLineRunner) runner, args);
			}
		}
	}

推送运行中事件ApplicationReadyEvent

0 = {SpringApplicationAdminMXBeanRegistrar@6596} 
1 = {BackgroundPreinitializer@6920} 
2 = {DelegatingApplicationListener@6921} 

启动完毕

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值