ApplicationContext
整体流程如下
源码走读:
创建ApplicationContext
源码如下:
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, "
+ "please specify an ApplicationContextClass",
ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
根据webApplicationType
创建ContextClass
如果是SERVLET
,则实例化一个org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
对象
如果是REACTIVE
,则实例化一个org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext
其他webApplicationType
的话就按照默认的走,默认实例化一个org.springframework.context.annotation.AnnotationConfigApplicationContext
webApplicationType
的由来
在实例化webApplicationType的时候,会初始化webApplicationType
。关键代码如下:
this.webApplicationType = WebApplicationType.deduceFromClasspath();
如下是设置webApplicationType
的代码
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;
}
可以看到,当ClassPath下面有org.springframework.web.reactive.DispatcherHandler
并且不包含org.springframework.web.servlet.DispatcherServlet
和org.glassfish.jersey.servlet.ServletContainer
的时候。则认为是REACTIVE
的应用。会在后面的流程中,启动reactive web服务器。
非REACTIVE
应用的场景下,如果classPath下面包含javax.servlet.Servlet
和org.springframework.web.context.ConfigurableWebApplicationContext
的时候,则认为不是web应用,不会启动内嵌的webServer
以上两种情况,即不是REACTIVE
也不是非WEB
应用,则认为是SERVLET
应用,会启动内嵌的servlet web服务器
本案例以Servlet应用为例,分析
AnnotationConfigServletWebServerApplicationContext
接口:
AnnotationConfigRegistry
定义了一个annotationConfigApplicationContext
的通用方法,一个是register
一个是scan
。
register
顾名思义就是注册bean到BeanFactory
中。
而scan就是扫描指定basepackages
下的所有bean
可以看到AnnotationConfigRegistry
的实现类有包含了servlet
,react
以及非web的ApplicationContext
继承父类:
AnnotationConfigServletWebServerApplicationContext->ServletWebServerApplicationContext->GenericWebApplicationContext->GenericApplicationContext->AbstractApplicationContext->DefaultResourceLoader
顺便溜一句
Java实例化一个对象的时候,父类和子类的初始化顺序。
父类的静态成员变量和静态代码块
子类的静态成员变量和静态代码块
父类中普通成员变量和代码块,父类的构造函数
子类中普通成员变量和代码块,子类的构造函数
巧记:
1、静态成员变量和静态代码,是类初始化的时候优先初始化的。
2、new一个对象的时候,有个前提就是类初始化好了,才会实例化一个对象。
所以先静态后普通,先爸爸后儿子。
所以我们先看下父类的各种重要属性:
抽象类AbstractApplicationContext
AbstactApplicationContext
定义类一个ApplicationContext
的共有的属性和方法,看一下关键属性。
beanFactoryPostProcessors
refresh
阶段,需要调用BeanFactoryPostProcessor的postProcessBeanFactory()
方法,去对BeanFactory
进行处理。
beanFactoryPostProcessors
就是存储后处理器的列表。
一般在初始化器ApplicationContextInitializer
或者监听器ApplicationListener
中添加。以为上面说了,这个BeanFactoryPostProcessor
是ApplicationContext
在reresh
的时候执行的。那也就是在refresh
之前要进行添加好。在refresh
之前,那也就是初始化器,以及监听器监听到在在refresh之前的事件。
如:ConfigurationWarningsApplicationContextInitializer和SharedMetadataReaderFactoryContextInitializer
是在初始化阶段添加ConfigurationWarningsPostProcessor
和CachingMetadataReaderFactoryPostProcessor
这两个后处理器的。
比如ConfigFileApplicationListener
就是在ApplicationPreparedEvent
阶段,添加了PropertySourceOrderingPostProcessor
后处理器到beanFactoryPostProcessors
中。
lifecycleProcessor
在ApplicationContext
各个阶段的生命周期回调。原理是AbstractApplicationContext
实现了ConfigurableApplicationContext
接口里面的生命周期相关函数。
比如在refresh完成后,根据配置执行registerShutdownHook,也就是注册一个JVM shutdown的hook。在JVM shutdown的时候进行回调处理。就调用的是lifecycleProcessor
的处理能力。
父类GenericApplicationContext
GenericApplicationContext
实现了BeanDefinitionRegistry
接口,继承AbstractApplicationContext
。
实现了BeanDefinitionRegistry
,说明其具备对BeanDefinition
的增删改查的能力。
GenericApplicationContext
典型用法是通过BeanDefinitionRegistry
接口的实现,去注册``BeanDefinition。之后通过调用
refresh()`去初始化这些Bean。
相比于其他ApplicationContext
,GenericApplicationContext
在创建好以后beanFactory
就已经初始化完成了。refresh
只能调用一次。
而其他的ApplicationContext
,在每次refresh的时候会其创建一个内部的beanFactory。
属性
beanFactory
BeanFactory
是属于GenericApplicationContext
的属性。在GenericApplicationContext
的无参构造方法有这么一条,说明beanFactory
是一个DefaultListableBeanFactory
实例
BeanFactory顾名思义,是Bean的工厂,先注册Bean,后访问Bean。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
AnnotationConfigServletWebServerApplicationContext
看下构造方法:
public AnnotationConfigServletWebServerApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
AnnotatedBeanDefinitionReader
这个Reader是用于读取class文件。在AnnotatedBeanDefinitionReader
对象实例化的过程中,会注册一些BeanPostProcessor
和BeanFactoryPostProcessor
。这些处理器会在后面对应的流程中用到。
源码如下:是AnnotatedBeanDefinitionReader
的构造方法。
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);
}
重点看下最后一句AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the 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));
}
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));
}
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));
}
return beanDefs;
}
可以看到在BeanFactory
中注册一些spring内部处理的Bean。注意:BeanFactory中有存储Bean定义的beanDefinitionMap
,也有beanPostProcessors
,本环节只是讲如下一些内部的bean注册到beanMap中,这些bean如下所示:
解析@Configuration
的CONFIGURATION_BEAN_NAME_GENERATOR(org.springframework.context.annotation.internalConfigurationBeanNameGenerator)
,也就是ConfigurationClassPostProcessor
类。
解析@Autowired
的AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME(org.springframework.context.annotation.internalAutowiredAnnotationProcessor)
,也就是AutowiredAnnotationBeanPostProcessor
类
解析@Required
的REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME(org.springframework.context.annotation.internalRequiredAnnotationProcessor)
,也就是RequiredAnnotationBeanPostProcessor
类
解析JSR-250
规范注解的COMMON_ANNOTATION_PROCESSOR_BEAN_NAME(org.springframework.context.annotation.internalCommonAnnotationProcessor)
,也就是CommonAnnotationBeanPostProcessor
类
以及后面注册的一些ListenerFactory
。
总结一下,这些Bean
,要么是BeanPostProcessor
实现类,要么就是ApplicationContextAware
。
这些Bean注册后,在refresh
后面的流程中都会用到,比如BeanPostPorcessor会在registerBeanPostProcessors
中用到。
ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner
是一个扫描指定类路径中注解Bean定义的扫描器,在它初始化的时候,会初始化一些需要被扫描的注解,初始化用于加载包下的资源的