目录
2. 创建SpringApplication后执行run方法
(1)SpringApplication#createApplicationContext
(2)SpringApplication#prepareContext
(3)SpringApplication#refreshContext
③ invokeBeanFactoryPostProcessors
⑥ initApplicationEventMessageMulticaster
⑨ finishBeanFactoryInitialization
基于第一章的Hello World项目。
一、入口类DemoApplication
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
二、进入SpringApplication的run方法
1. 跳到这里,创建SpringApplication对象
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return (new SpringApplication(primarySources)).run(args);
}
(1)SpringApplication构造函数
发现个很骚的东西,null强转为ResourceLoader(该类其他地方也出现过null强转),暂且认为除了增强可读性,还便于后续添加新方法时,可以方法重载。
public SpringApplication(Class<?>... primarySources) {
// 这个除了可读性,应当是便于后续添加新方法时,可以方法重载
this((ResourceLoader)null, primarySources);
}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// 初始化属性
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.resourceLoader = resourceLoader;
// 断言判断非空
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
// 判断当前环境是
// ① NONE(标准环境(classPath下没有javax.servlet.Servlet以及
// org.springframework.web.context.ConfigurableWebApplicationContext)、
// ② SERVLET(Servlet环境)、
// ③ REACTIVE(响应式)
// (这里是SERVLET)
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 扫描当前路径下META-INF/spring.factories文件的,加载ApplicationContextInitializer接口实例
// 设置初始化器,这些初始化器将在容器刷新前回调,原理是通过SpringFactoriesLoader的loadFactoryNames方法
// 在 spring.factories文件中找到的ApplicationContextInitializer接口的配置的实现类的全限定类名,并实例化。
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 扫描当前路径下META-INF/spring.factories文件的,加载ApplicationListener接口实例
// 设置监听器,目的同上
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
// 去栈帧中寻找方法名为main的方法来得到入口类的名字,反射获取类信息Class,并设置为mainApplicationClass
// (这里是DemoApplication全类名)
this.mainApplicationClass = this.deduceMainApplicationClass();
}
1、ApplicationContextInitializer是Spring框架原有的东西,这个类的主要作用就是在ConfigurableApplicationContext类型(或者子类型)的ApplicationContext做refresh之前,允许我们对ConfiurableApplicationContext的实例做进一步的设置和处理。
2、在一个Springboot应用中,classpath上会包含很多jar包,有些jar包需要在ConfigurableApplicationContext#refresh()调用之前对应用上下文做一些初始化动作,因此它们会提供自己的ApplicationContextInitializer实现类,然后放在自己的META-INF/spring.factories属性文件中,这样相应的ApplicationContextInitializer实现类就会被SpringApplication#initialize发现。
3、 可以分别实现ApplicationContextInitalizer接口和ApplicationListener接口来印证:
- 实现两接口:
/** * 自定义初始化器 * @author ZRH * @version 1.0.0 * @date 2020/9/1 */ public class MyInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext applicationContext) { System.out.println("MyInitializer初始化完成"); } }
/** * 自定义监听器 * @author ZRH * @version 1.0.0 * @date 2020/9/1 */ public class MyListener implements ApplicationListener<ApplicationEvent> { @Override public void onApplicationEvent(ApplicationEvent event) { System.out.println("MyListener"); } }
- 创建META-INF/spring.factories
- 接着再SpringApplication#getSpringFactoriesInstances方法中
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes , Object... args) { ClassLoader classLoader = this.getClassLoader(); // 加载META-INF/spring.factories得到实现ApplicationContextInitializer接口的所有实现类 // (ApplicationListener类似) Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader)); // 根据名称利用反射创建实例 List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader , args, names); // AnnotationAwareOrderComparator是OrderComparator的子类, // 用来支持Spring的Ordered类、@Order注解和@Priority注解。按优先级排序。 AnnotationAwareOrderComparator.sort(instances); return instances; }
- 加载工厂,跳到SpringFactoriesLoader#loadFactoryNames方法,
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) { String factoryTypeName = factoryType.getName(); return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList()); }
- 再看SpringFactoriesLoader#loadSpringFactories方法
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) { MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader); if (result != null) { return result; } else { try { Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories"); LinkedMultiValueMap result = new LinkedMultiValueMap(); while(urls.hasMoreElements()) { // 找到在项目中得spring.factories完整路径 URL url = (URL)urls.nextElement(); UrlResource resource = new UrlResource(url); // 读取文件中的属性,即我们写的那两个类 Properties properties = PropertiesLoaderUtils.loadProperties(resource); Iterator var6 = properties.entrySet().iterator(); while(var6.hasNext()) { Entry<?, ?> entry = (Entry)var6.next(); // 这里的factoryTypeName依次是接口ApplicationContextInitializer、ApplicationListener String factoryTypeName = ((String)entry.getKey()).trim(); String[] var9 = StringUtils .commaDelimitedListToStringArray((String)entry.getValue()); int var10 = var9.length; for(int var11 = 0; var11 < var10; ++var11) { // 这里的factoryImplementationName依次是自定义的MyInitializer、MyListener String factoryImplementationName = var9[var11]; result.add(factoryTypeName, factoryImplementationName.trim()); } } } cache.put(classLoader, result); return result; } catch (IOException var13) { throw new IllegalArgumentException ("Unable to load factories from location [META-INF/spring.factories]", var13); } } }
可以看到,它找的路径便是META-INF/spring.factories,这就是为什么我们在那配置,写死了。
此外,classLoader.getResources是调用加载器实例来加载资源,而ClassLoader.getSystemResources是调用系统加载器加载资源;Spring Boot项目打包之后应该用Spring提供的ClassLoader来加载资源(通过自定义类的getClassLoader即可),否则可能会出错。
properties则是读取spring.factories后取得的:
而且执行顺序:自定义META-INF/spring.factories从上到下 > spring-boot-x.x.x.REALEASE.jar/META-INF/spring.factories > spring-boot-autoconfigure-x.x.x.RELEASE.jar/META-INF/spring.factories > spring-beans-x.x.x.RELEASE.jar/META-INF/spring.factories。
这种思路就是SPI,一种服务提供发现机制(Service Provider Interface)。大体是,服务的提供者在classpath下的META-INF/services/目录里创建一个以服务接口命名的文件,内容就是这个接口的具体实现类名。当其他的程序需要这个服务时,只需查这个jar包的META-INF/services/中的相应配置文件内容里的具体实现类名,通过反射获取实例,使用该服务。
- 加载完成之后,就依次得到实现ApplicationContextInitializer接口和ApplicationListener的所有实现类了:
其中:
实现类
作用 ConfigurationWarningsApplicationContextInitializer 报告IOC容器的一些常见的错误配置 ContextIdApplicationContextInitializer 设置Spring应用上下文的ID DelegatingApplicationContextInitializer 加载 application.properties 中 context.initializer.classes 配置的类 ServerPortInfoApplicationContextInitializer 将内置servlet容器实际使用的监听端口写入到 Environment 环境属性中 SharedMetadataReaderFactoryContextInitializer 创建一个 SpringBoot 和ConfigurationClassPostProcessor 共用的 CachingMetadataReaderFactory 对象 ConditionEvaluationReportLoggingListener 将 ConditionEvaluationReport 写入日志
其中:
实现类 作用 ClearCachesApplicationListener
应用上下文加载完成后对缓存做清除工作 ParentContextCloserApplicationListener 监听双亲应用上下文的关闭事件并往自己的子应用上下文中传播 FileEncodingApplicationListener 检测系统文件编码与应用环境编码是否一致,如果系统文件编码和应用环境的编码不同则终止应用启动 AnsiOutputApplicationListener 根据 spring.output.ansi.enabled 参数配置 AnsiOutput ConfigFileApplicationListener 从常见的那些约定的位置读取配置文件 DelegatingApplicationListener 监听到事件后转发给 application.properties 中配置的 context.listener.classes 的监听器 ClasspathLoggingApplicationListener 对环境就绪事件 ApplicationEnvironmentPreparedEvent 和应用失败事件 ApplicationFailedEvent 做出响应 LoggingApplicationListener 配置 LoggingSystem。使用 logging.config 环境变量指定的配置或者缺省配置 LiquibaseServiceLocatorApplicationListener 使用一个可以和 SpringBoot 可执行jar包配合工作的版本替换 LiquibaseServiceLocator BackgroundPreinitializer 使用一个后台线程尽早触发一些耗时的初始化任务
① 枚举类WebApplicationType的deduceFromClasspath()
该枚举类有三个常量:
NONE,
SERVLET,
REACTIVE;
static WebApplicationType deduceFromClasspath() {
if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null)
&& !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null)
&& !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {
return REACTIVE;
} else {
String[] var0 = SERVLET_INDICATOR_CLASSES;
int var1 = var0.length;
for(int var2 = 0; var2 < var1; ++var2) {
String className = var0[var2];
if (!ClassUtils.isPresent(className, (ClassLoader)null)) {
return NONE;
}
}
return SERVLET;
}
}
代表着Spring5的两种web技术栈:servlet(Spring MVC)和reactive(Spring WebFlux)。
REACTIVE是响应式编程的东西,指的是应用WebFlux框架下的应用环境,是NIO同步非阻塞IO,未来可能替代当前的MVC
2. 创建SpringApplication后执行run方法
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class
, new Class[]{ConfigurableApplicationContext.class}, context);
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
// 刷新后的处理,是个空实现
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass))
.logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
- 计时
计时器,监控启动时间
StopWatch stopWatch = new StopWatch(); stopWatch.start();
- 异常解析器集合的初始化
SpringBootExceptionReporter是一个异常解析器,实现类只有一个是FailureAnalyzers,用于打印异常信息,这个集合在下面new DefaultApplicationArguments处初始化,集合里面装了针对各式各样的异常解析器,在catch到异常后,会遍历这个集合,寻找合适的异常解析器,然后打印异常日志。
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
- 容器运行期间的事件监听
内部调getSpringFactoriesInstances方法,取spring.factories中所有的SpringApplicationRunListener,对外暴露封装所有的SpringApplicationRunListener的SpringApplicationRunListeners,用于容器启动间的事件发布到所有的SpringApplicationRunListener中。
SpringApplicationRunListener与ApplicationListener的区别是SpringApplicationRunListener比ApplicationListener更靠前,SpringApplicationRunListener监听的是SpringApplication相关方法的执行,属于第一层监听器,他会发布相应的事件给ApplicationListener。
SpringApplicationRunListeners listeners = this.getRunListeners(args); listeners.starting();
- 初始化Environment
根据不同的webApplicationType完成Environment的初始化,一般是使用StandardServletEnvironment实现类,Environment用于描述应用程序当前的运行环境,其抽象了两个方面的内容:配置文件(profile)和属性(properties),其实就是对应的配置文件、环境变量、命令行参数里面的内容。这里Environment构建完成时发布了environmentPrepared事件,并且将最新的配置值绑定到了SpringbootApplication中,也就是当前的对象中。比如yml里面配的spring. main开头的一些属性值。
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
- 设置Banner
打印Banner,会判断模式是否为隐藏(MODE.OFF),不是则打印到控制台,可自定义Banner在类路径下的banner.txt。
Banner printedBanner = this.printBanner(environment);
- 创建ApplicationContext
根据webApplicationType,反射创建不同的ApplicationContext实现(这里Servlet是AnnotationConfigServletWebServerApplicationContext,在他的父类GenericApplicationContext构造方法中,其中注入了一个DefaultListableBeanFactory,这个BeanFactory很关键,实际上AnnotationConfigServletWebServerApplicationContext的BeanFactory能力就是从DefaultListableBeanFactory扩展而来。
在这一步中也注册了ConfigurationClassPostProcessor、DefaultEventListenerFactory、EventListenerMethodProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor这些beanDefinition,作为基础组件。ConfigurationClassPostProcessor是BeanFactoryPostProcessor,负责在容器刷新时加载扫描配置类注解进行组件解析,注册BeanDefinition。
context = this.createApplicationContext();
- 获取异常报告事件监听
获取异常报告事件监听,创建流程是通过SpringFactoriesLoader获取到所有实现SpringBootExceptionReporter接口的class。
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class , new Class[]{ConfigurableApplicationContext.class}, context);
- 初始化ApplicationContext
① 将准备好的Environment设置给ApplicationContext
② 进一步执行ApplicationContext的后置处理,包括注册BeanName生成器, 设置资源加载器和类加载器,设置类型转换器ConversionService等。
③ 遍历调用所有的ApplicationContextInitializer的initialize()方法来对已经创建好的ApplicationContext进行进一步的处理。
④ 调用SpringApplicationRunListener的contextPrepared()方法,通知所有的监听者:ApplicationContext已经准备完毕。
⑤ 创建启动类的beanDefiniton注册到容器中。
⑥ 调用SpringApplicationRunListener的contextLoaded()方法,通知所有的监听者:ApplicationContext已经装载完毕。
this.refreshContext(context);
- 计时结束
stopWatch.stop();
- 运行器回调
即实现了ApplicationRunner接口或CommandLineRunner接口的bean
this.callRunners(context, applicationArguments);
(1)SpringApplication#createApplicationContext
根据web应用的类型来创建上下文对象
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 var3) {
throw new IllegalStateException
("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
}
}
return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
}
这里是生成AnnotationConfigServletWebServerApplicationContext
public AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory) {
super(beanFactory);
this.annotatedClasses = new LinkedHashSet();
// 创建Spring核心组件
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
(2)SpringApplication#prepareContext
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment
, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments
, Banner printedBanner) {
// 设置标准servlet环境
context.setEnvironment(environment);
this.postProcessApplicationContext(context);
// 添加之前的那些初始化器
this.applyInitializers(context);
listeners.contextPrepared(context);
if (this.logStartupInfo) {
this.logStartupInfo(context.getParent() == null);
this.logStartupProfileInfo(context);
}
// 创建默认bean工厂类
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
// 默认为false,即不支持名称相同的bean被覆盖
((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding
(this.allowBeanDefinitionOverriding);
}
// 默认不延迟初始化
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// 加载资源
Set<Object> sources = this.getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
this.load(context, sources.toArray(new Object[0]));
listeners.contextLoaded(context);
}
(3)SpringApplication#refreshContext
直接跳到AbstractApplicationContext#refresh
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
// 初始化前的预处理,初始化Environment里面的PropertySources
this.prepareRefresh();
// 获取BeanFactory,直接返回的是前面初始化的beanFactory,只不过设置了一下SerializationId
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册bean的后置处理器
this.registerBeanPostProcessors(beanFactory);
// 初始化MessageSource组件。MessageSource组件主要用来实现国际化、消息解析处理。
this.initMessageSource();
// 初始化事件派发器
this.initApplicationEventMulticaster();
// 留给子类重写
this.onRefresh();
// 注册事件监听器
this.registerListeners();
// 初始化所有剩下的单例Bean
this.finishBeanFactoryInitialization(beanFactory);
// 完成容器的创建工作
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
// 清除缓存
this.resetCommonCaches();
}
}
}
① prepareBeanFactory
BeanFactory的预处理配置
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(this.getClassLoader());
// 设置BeanFactory的类加载器、表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory
.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
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);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 添加AspectJ
if (beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
}
上述代码中:
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
在容器注册了ApplicationContextAwareProcessor这个Bean后置处理器,用于处理实现了XXXAware接口的bean,调用其setXXX方法。这个Bean后处理器将实现了其下几个Aware的bean分别回调对应的方法。
配置ignoreDependencyInterface,即忽略这些自动注入,但实测@Autowired注入时还是能装配。避免这些beanDefinition设置了自动注入(即AutowireMode)。若自动注入生效,该Bean的setXXX方法将被自动注入,那么为了避免和XXXAware接口冲突,应进行了忽略。
beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
添加一些自动注入支持,包含BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this);
配置一个可加载所有监听器的组件,用于收集所有实现了ApplicationListener接口的bean并收集到容器中的一个集合中
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
注册了默认的运行时环境、系统配置属性、系统环境的信息。
if (!beanFactory.containsLocalBean("environment")) { beanFactory.registerSingleton("environment", this.getEnvironment()); } if (!beanFactory.containsLocalBean("systemProperties")) { beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean("systemEnvironment")) { beanFactory.registerSingleton("systemEnvironment" , this.getEnvironment().getSystemEnvironment()); }
② postProcessBeanFactory
准备BeanFactory完成后进行的后置处理
以servlet为例,这里的ApplicationContext实现实际上为AnnotationConfigServletWebServerApplicationContext。在该类中该方法主要是完成了:
看AnnotationConfigServletWebServerApplicationContext#postProcessBeanFactory:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.postProcessBeanFactory(beanFactory); if (this.basePackages != null && this.basePackages.length > 0) { this.scanner.scan(this.basePackages); } if (!this.annotatedClasses.isEmpty()) { this.reader.register(ClassUtils.toClassArray(this.annotatedClasses)); } }
看ServletWebServerApplicationContext#postProcessBeanFactory:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); this.registerWebApplicationScopes(); }
其中:往容器注册了一个bean的后置处理器处理ServletContextAware和ServletConfigAware,用于注入ServletContext和ServletConfig。
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
往容器注册Scope,Scope描述的是Spring容器如何新建Bean实例的,这里注册了Request以及Session两个Scope并且注册ServletRequest、ServletResponse、HttpSession、WebRequest为自动装配。
this.registerWebApplicationScopes();
当判断容器的basePackages属性不为null的时候进行包扫描。
当判断容器的annotatedClasses属性不为null也进行注册。
if (this.basePackages != null && this.basePackages.length > 0) { this.scanner.scan(this.basePackages); } if (!this.annotatedClasses.isEmpty()) { this.reader.register(ClassUtils.toClassArray(this.annotatedClasses)); }
③ invokeBeanFactoryPostProcessors
执行BeanFactory创建后的后置处理器,这一步里面会处理ConfigurationClassPostProcessor这个beanDefinition后置处理器完成所有的beanDefinition注册。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 执行BeanFactory后置处理器
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory
, this.getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
获取已经注册到容器的beanFactoryPostProcessor的beanFactoryPostProcessors(这里用了容器内beanFactoryPostProcessors这个变量存的而不是从beanDefinition获取的)
调用了PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory
, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 用于存放已经执行了的后置处理器名
Set<String> processedBeans = new HashSet();
ArrayList regularPostProcessors;
ArrayList registryProcessors;
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
// 这里要判断BeanFactory的类型,默认SpringBoot创建的BeanFactory是DefaultListableBeanFactory,它便是。
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
regularPostProcessors = new ArrayList();
registryProcessors = new ArrayList();
// 遍历已经注册到beanFactory的BeanFactoryPostProcessor后置处理器
// ,然后分类为regularPostProcessors和registryProcessors
Iterator var6 = beanFactoryPostProcessors.iterator();
while (var6.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor) var6.next();
// 获取容器内已注册的beanDefinition中BeanDefinitionRegistryPostProcessor类型的bean
// 筛选实现PriorityOrdered接口的,再排序,然后回调其postProcessBeanDefinitionRegistry。
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
// 这个currentRegistryProcessors变量用于分阶段执行方法,因为有PriorityOrdered和Ordered接口的存在。
currentRegistryProcessors = new ArrayList();
// 下面几大段代码:获取容器内已注册的beanDefinition中BeanDefinitionRegistryPostProcessor类型的bean
// 并添加到processedBeans,会根据是否实现PriorityOrdered接口、Ordered接口进行排序(大体顺序是
// PriorityOrdered > Ordered > 没实现接口的,而同一接口的按方法返回值确定顺序),
// 然后调用invokeBeanDefinitionRegistryPostProcessors执行其postProcessBeanDefinitionRegistry方法。
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class
, true, false);
String[] var16 = postProcessorNames;
var9 = postProcessorNames.length;
int var10;
String ppName;
for (var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName
, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//添加到registryProcessors
registryProcessors.addAll(currentRegistryProcessors);
//执行
// 这里面会执行最重要的ConfigurationClassPostProcessor,他会对当前beandifinitonMap中的带有configraution注解的
// 进行处理,比如处理@Component 、@ComponentScan 、@Import 、@ImportResource、@PropertySource 、@Bean注解,
// 注册所有的beanDefinition
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 接下来,调用实现Ordered接口的BeanDefinitionRegistryPostProcessors。
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class
, true, false);
var16 = postProcessorNames;
var9 = postProcessorNames.length;
for (var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName
, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//添加到registryProcessors
registryProcessors.addAll(currentRegistryProcessors);
// 执行
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 最后,调用所有其他BeanDefinitionRegistryPostProcessor(没实现上面两接口的)
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class
, true, false);
String[] var19 = postProcessorNames;
var10 = postProcessorNames.length;
for (int var26 = 0; var26 < var10; ++var26) {
String ppName = var19[var26];
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName
, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
//排序添加执行
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 回调所有BeanFactoryPostProcessor的postProcessBeanFactory方法:
// 先回调BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
// 再调用BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors((Collection) registryProcessors
, (ConfigurableListableBeanFactory) beanFactory);
invokeBeanFactoryPostProcessors((Collection) regularPostProcessors
, (ConfigurableListableBeanFactory) beanFactory);
} else {
// 如果BeanFactory没有实现BeanDefinitionRegistry接口
// 调用在上下文实例中注册的工厂处理器。
invokeBeanFactoryPostProcessors((Collection) beanFactoryPostProcessors
, (ConfigurableListableBeanFactory) beanFactory);
}
// 下面的部分是回调BeanFactoryPostProcessor,思路与上面的几乎一样
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class
, true, false);
regularPostProcessors = new ArrayList();
registryProcessors = new ArrayList();
currentRegistryProcessors = new ArrayList();
postProcessorNames = postProcessorNames;
int var20 = postProcessorNames.length;
String ppName;
for (var9 = 0; var9 < var20; ++var9) {
ppName = postProcessorNames[var9];
if (!processedBeans.contains(ppName)) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
registryProcessors.add(ppName);
} else {
currentRegistryProcessors.add(ppName);
}
}
}
sortPostProcessors(regularPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection) regularPostProcessors
, (ConfigurableListableBeanFactory) beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList(registryProcessors.size());
Iterator var21 = registryProcessors.iterator();
while (var21.hasNext()) {
String postProcessorName = (String) var21.next();
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection) orderedPostProcessors
, (ConfigurableListableBeanFactory) beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size());
Iterator var24 = currentRegistryProcessors.iterator();
while (var24.hasNext()) {
ppName = (String) var24.next();
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors((Collection) nonOrderedPostProcessors
, (ConfigurableListableBeanFactory) beanFactory);
// 清理缓存
beanFactory.clearMetadataCache();
}
可以看看类之间的关系:
看ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 获取容器Id,获取其是否调用过,如果没有则继续执行processConfigBeanDefinitions
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
} else if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
} else {
this.registriesPostProcessed.add(registryId);
this.processConfigBeanDefinitions(registry);
}
}
看 ConfigurationClassPostProcessor#processConfigBeanDefinitions
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList();
String[] candidateNames = registry.getBeanDefinitionNames();
String[] var4 = candidateNames;
int var5 = candidateNames.length;
for (int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (this.logger.isDebugEnabled()) {
this.logger.debug(
"Bean definition has already been processed as a configuration class: " + beanDef);
}
} else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef
, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
if (!configCandidates.isEmpty()) {
// 对配置类进行排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 加载获取BeanNameGenerator
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
"org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 初始化配置类解析器
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader
, this.componentScanBeanNameGenerator, registry);
// 需要解析的配置类集合
Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
//已经解析的配置类集合
HashSet alreadyParsed = new HashSet(configCandidates.size());
do {
// 解析配置类。很关键
parser.parse(candidates);
// 校验
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry
, this.sourceExtractor, this.resourceLoader, this.environment
, this.importBeanNameGenerator, parser.getImportRegistry());
}
// 将上面解析配置类得到的BeanDefinition注册到BeanDefinitionMap中。
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//当前的beanDefinitinoNames
String[] newCandidateNames = registry.getBeanDefinitionNames();
//上一次解析之前的beanDefinitinoNames
Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
//这次解析的beanDefinitinoNames
Set<String> alreadyParsedClasses = new HashSet();
Iterator var12 = alreadyParsed.iterator();
while (var12.hasNext()) {
ConfigurationClass configurationClass = (ConfigurationClass) var12.next();
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
String[] var23 = newCandidateNames;
int var24 = newCandidateNames.length;
// 遍历当前bdNames,若不是以前有的,并且是配置类,并且没有被解析到,则添加到candidates,
// 下一次循环再解析一次
for (int var14 = 0; var14 < var24; ++var14) {
String candidateName = var23[var14];
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd
, this.metadataReaderFactory) && !alreadyParsedClasses.contains(
bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
} while (!candidates.isEmpty());
// 将ImportRegistry注册为Bean,以支持ImportAware 和@Configuration类
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
// 清除缓存
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
}
确定配置类和组件:
checkConfigurationClassCandidate()会判断是否为一个配置类,并为BeanDefinition设置属性为lite或者full。如果加了@Configuration,那么对应的BeanDefinition为full;如果加了@Bean,@Component,@ComponentScan,@Import,@ImportResource这些注解,则为lite。lite和full均表示这个BeanDefinition对应的类是一个配置类,最后都加入到configCandidates
String[] candidateNames = registry.getBeanDefinitionNames(); String[] var4 = candidateNames; int var5 = candidateNames.length; for (int var6 = 0; var6 < var5; ++var6) { String beanName = var4[var6]; BeanDefinition beanDef = registry.getBeanDefinition(beanName); if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) { if (this.logger.isDebugEnabled()) { this.logger.debug( "Bean definition has already been processed as a configuration class: " + beanDef); } } else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef , this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } }
由于篇幅原因,上边关于解析注解,让系统完成自动配置功能的实现,放在我的“【SpringBoot】二、SpringBoot启动流程之自动配置(源码)”。
请注意:
解析完配置类后,把结果传给this.reader.loadBeanDefinitions(configClasses);这一步很重要,将beanDefinition注册到beanDefinitionMap,让Spring IOC容器想用时去获取。简单看下源码:
跳到ConfigurationClassBeanDefinitionReader#loadBeanDefinitions,再到ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass,再到ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass,再到DefaultListableBeanFactory#registerBeanDefinition:
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { // 验证beanDefinition,只验证一项内容:beanDefinition不能同时具有overrideMethod // 和factoryMethod两个属性,如果两个都有,就验证失败 ((AbstractBeanDefinition)beanDefinition).validate(); } catch (BeanDefinitionValidationException var8) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8); } } // 创建一个临时变量,用于存放之前同名的beanDefinition(如果有的话) BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName); // 如果同名了。Spring这里有一个标识位allowBeanDefinitionOverriding,表示是否允许BeanDefinition被覆盖。 // 一般这个值都是false,除非特定的业务情境下,允许覆盖同名的BeanDefinition。 // 如果allowBeanDefinitionOverriding是false的话,就抛出异常,表示beanName冲突了 // 如果allowBeanDefinitionOverriding是true的话,就直接覆盖原来的beanDefinition if (existingDefinition != null) { if (!this.isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } if (existingDefinition.getRole() < beanDefinition.getRole()) { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (this.logger.isDebugEnabled()) { this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (this.logger.isTraceEnabled()) { this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } // 将beanDefinition放入到beanDefinitionMap中,这个beanDefinition至此加入了SpringIOC(下同) this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (this.hasBeanCreationStarted()) { synchronized(this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; this.removeManualSingletonName(beanName); } } else { this.beanDefinitionMap.put(beanName, beanDefinition); // 如果没有同名的BeanDefinition,就把beanName放入到beanDefinitionNames集合中 // beanDefinitionNames是一个Set,存储所有BeanDefinition的name,不是别名,是为了加速BeanDefinition的名称检查 this.beanDefinitionNames.add(beanName); this.removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition == null && !this.containsSingleton(beanName)) { if (this.isConfigurationFrozen()) { this.clearByTypeCache(); } } else { this.resetBeanDefinition(beanName); } }
添加的语句便是:this.beanDefinitionMap.put(beanName, beanDefinition);这样,就将beanDefinition加入“资源池”beanDefinitionMap,后面Spring IOC在需要的时候,就向资源池要对象,这便是依赖控制反转。
④ registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
和③类似,
注册bean后置处理器,含MergedBeanDefinitionPostProcessor:
注册逻辑跟注册beanFactoryPostProcessor差不多,注册顺序都会判断priorityOrdered与Ordered接口,并且先注册MergedBeanDefinitionPostProcessor再注册beanFactoryPostProcessor。
这里有两个MergedBeanDefinitionPostProcessor,一个是AutowiredAnnotationBeanPostProcessor,一个是ApplicationListenerDetector。
- AutowiredAnnotationBeanPostProcessor 会解析bean的自动注入属性,判断是否有需要依赖的项,并通过registerExternallyManagedConfigMember注册依赖项。
- ApplicationListenerDetector 作用,收集一个beanName为键,是否单例为值的map
⑤ initMessageSource
messageSource主要是spring提供的国际化组件,
⑥ initApplicationEventMessageMulticaster
这里也是扫描beanDefinition中有没有applicationEventMulticaster,如果没有则使用默认的SimpleApplicationEventMulticaster,这里需要注意的是,在这之前,springboot启动过程中其实也有事件分发,比如SpringApplicationRunListener的start方法在容器开始的时候就被调用了,如何做的?实际上它是使用的内部的SimpleApplicationEventMulticaster来完成的事件广播。而这里和后面将要注册的listener不是使用的同一个事件广播器。
⑦ onRefresh
SERVLET类型的web应用就跳到了ServletWebServerApplicationContext#onRefresh
protected void onRefresh() {
super.onRefresh();
try {
this.createWebServer();
} catch (Throwable var2) {
throw new ApplicationContextException("Unable to start web server", var2);
}
}
ServletWebServerApplicationContext#createWebServer
// 创建web服务
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = this.getServletContext();
// 刚开始都为null
if (webServer == null && servletContext == null) {
// 获取创建容器的工厂,可以通过WebServerFactoryCustomizer接口对这个工厂进行自定义设置
ServletWebServerFactory factory = this.getWebServerFactory();
// 创建web容器,这个方法为wrapper设置了servletClass为DispatcherServlet
this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
this.getBeanFactory().registerSingleton("webServerGracefulShutdown"
, new WebServerGracefulShutdownLifecycle(this.webServer));
this.getBeanFactory().registerSingleton("webServerStartStop"
, new WebServerStartStopLifecycle(this, this.webServer));
} else if (servletContext != null) {
try {
this.getSelfInitializer().onStartup(servletContext);
} catch (ServletException var4) {
throw new ApplicationContextException("Cannot initialize servlet context", var4);
}
}
this.initPropertySources();
}
看下TomcatServletServiceFactory#getWebServer
public WebServer getWebServer(ServletContextInitializer... initializers) {
if (this.disableMBeanRegistry) {
Registry.disableRegistry();
}
// 创建tomcat
Tomcat tomcat = new Tomcat();
// 设置工作目录
File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
// 初始化tomcat的连接器,默认NIO模式,可以通过WebServerFactoryCustomizer改变具体模式
Connector connector = new Connector(this.protocol);
connector.setThrowOnFailure(true);
tomcat.getService().addConnector(connector);
// 自定义连接器
this.customizeConnector(connector);
tomcat.setConnector(connector);
// 设置自动部署为false
tomcat.getHost().setAutoDeploy(false);
this.configureEngine(tomcat.getEngine());
Iterator var5 = this.additionalTomcatConnectors.iterator();
while(var5.hasNext()) {
Connector additionalConnector = (Connector)var5.next();
tomcat.getService().addConnector(additionalConnector);
}
// 准备上下文
this.prepareContext(tomcat.getHost(), initializers);
// 最后返回一个Tomcat服务器
return this.getTomcatWebServer(tomcat);
}
再进TomcatServletWebServerFactory#prepareContext
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
File documentRoot = this.getValidDocumentRoot();
TomcatEmbeddedContext context = new TomcatEmbeddedContext();
if (documentRoot != null) {
context.setResources(new TomcatServletWebServerFactory.LoaderHidingResourceRoot(context));
}
// 为TomcatEmbeddedContext对象设置属性
context.setName(this.getContextPath());
context.setDisplayName(this.getDisplayName());
context.setPath(this.getContextPath());
File docBase = documentRoot != null ? documentRoot : this.createTempDir("tomcat-docbase");
context.setDocBase(docBase.getAbsolutePath());
context.addLifecycleListener(new FixContextListener());
context.setParentClassLoader(this.resourceLoader != null ? this.resourceLoader.getClassLoader()
: ClassUtils.getDefaultClassLoader());
this.resetDefaultLocaleMapping(context);
this.addLocaleMappings(context);
try {
context.setCreateUploadTargets(true);
} catch (NoSuchMethodError var8) {
}
this.configureTldSkipPatterns(context);
WebappLoader loader = new WebappLoader();
loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
loader.setDelegate(true);
context.setLoader(loader);
if (this.isRegisterDefaultServlet()) {
this.addDefaultServlet(context);
}
if (this.shouldRegisterJspServlet()) {
this.addJspServlet(context);
this.addJasperInitializer(context);
}
context.addLifecycleListener(new TomcatServletWebServerFactory.StaticResourceConfigurer(context));
ServletContextInitializer[] initializersToUse = this.mergeInitializers(initializers);
host.addChild(context);
this.configureContext(context, initializersToUse);
this.postProcessContext(context);
}
⑧ registerListeners
注册监听器,并广播早期事件(只是一个供springboot自己用的一个扩展点,这个扩展点允许在后置处理器和监听器都被创建好,其余的单实例Bean还没有创建时广播一些早期事件),通过debug看这里目前没有任何早期事件存入
⑨ finishBeanFactoryInitialization
初始化其他的单例bean,解决了循环依赖
⑩ finishRefresh
清除资源缓存(如扫描的ASM元数据)、处理生命周期处理器(Lifecycle接口)、发布容器刷新完成的事件。ServletWebServerApplicationContext在最后会调用 WebServer 的start方法
总结
一、 创建SpringApplication,包括设置默认属性、web应用类型、初始化器与监听器、入口类的类信息等
二、 run
1. 监控容器启动时间
2. 初始化异常解析器集合
3. 监听容器启动间的事件
4. 根据web应用类型初始化Environment
5. 设置Banner
6. 根据web应用类型创建ApplicationContext,注册基础组件
7. 获取异常报告事件监听
8. prepareContext
(1)设置配置环境
(2)创建默认beanFactory类:DefaultListableBeanFactory
(3)加载资源
9. refreshContext,启动web容器
(1)prepareBeanFactory
① 设置类加载器、表达式解析器
② 设置一些自动注入与忽略自动注入的支持
③ 注册默认系统信息
(2)postProcessBeanFactory
① 往容器注册WebApplicationContextServletContextAwareProcessor
② 往容器注册Scope
③ 判断容器的basePackages、annotatedClasses属性是否为null
(3)invokeBeanFactoryPostProcessors
① beanFactory是BeanDefinitionRegistry类型
Ⅰ. 遍历已经注册到beanFactory的BeanFactoryPostProcessor后置处理器,然后分类为regularPostProcessors和registryProcessors
Ⅱ. 按【实现PriorityOrder接口->Order接口->没实现接口】顺序处理,再分别各自排序,添加到registryProcessors,最后后处理beanDefinition注册表
- 没有调用过则继续,去处理配置beanDefinition
- 根据@Component 、@ComponentScan 、@Import 、@ImportResource、@Configuration、@Bean等设beanDefinition属性为full或lite
- 配置类跑排序
- 解析配置类
➷ 依次处理每个@PropertySource、再是每个@ComponentScan、每个@Import、每个@ImportResource、配置类中@Bean注解的方法、存在父类则递归处理
- 将上面解析配置类得到的BeanDefinition注册到BeanDefinitionMap中
Ⅲ. 先回调BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法,再调用BeanFactoryPostProcessor的postProcessBeanFactory方法
② BeanFactory非BeanDefinitionRegistry类型,则调用在上下文实例中注册的工厂处理器
(4)registerBeanPostProcessors
(5)初始化MessageSource组件
(6)初始化事件派发器
(7)创建web容器
(8)注册事件监听器
(9)初始化所有剩下的单实例bean
(10)完成容器的创建工作
10. 停止计时
11. 运行器回调