Spring源码笔记5—AnotationConfigServletWebServerApplicationContext(SpringBoot默认容器)
GenericApplicationContext通用应用程序上下文

作用
1、继承AbstractApplicationContext,几乎可以把GenericApplicationContext等价于DefaultListableBeanFactory + 上下文刷新等其他功能
①该实现内部有一个 DefaultListableBeanFactory 实例,GenericApplicationContext基本就是对DefaultListableBeanFactory 做了个简易的封装,几乎所有方法都是使用了DefaultListableBeanFactory的方法去实现。
②可以采用混合方式处理bean的定义,而不是采用特定的bean定义方式来创建bean。
2、会暴露出底层关联的DefaultListableBeanFactory对象,ConfigurableListableBeanFactory getBeanFactory()
①基于底层关联的DefaultListableBeanFactory对象实现BeanDefinitionRegistry接口
②同时可以提供一些方法对DefaultListableBeanFactory的属性进行设置,比如setApplicationStartup、setAllowBeanDefinitionOverriding、setAllowCircularReferences等
3、支持设置ResourceLoader,重写了Resource getResource和Resource[] getResources,优先使用自定义的 ResourceLoader获取指定路径的资源 ;在处理Resource时,支持自定义的类加载器,如果没有自定义设置且设置了ResourceLoader,就取ResourceLoader里的
4、实现了AbstractApplicationContext类的模板方法
①obtainFreshBeanFactory刷新底层容器阶段的抽象方法refreshBeanFactory的实现
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) { throw new IllegalStateException() }
this.beanFactory.setSerializationId(getId());
}
②refreshBeanFactory/cancelRefresh/closeBeanFactory方法的实现,只是简单的对beanFactory.setSerializationId得设置为null
protected final void closeBeanFactory() {
this.beanFactory.setSerializationId(null);
}
5、提供一个新的注册bean定义的方法registerBean方法
①使用一个新的RootBeanDefinition子类ClassDerivedBeanDefinition(clazz)来封装bean定义,重写了其getPreferredConstructors方法,实现如下
通过反射clazz.getConstructors()返回公共public的构造器集合
②使用参数传递进来的BeanDefinitionCustomizer对BeanDefinition进行自定义处理
③ 把bean定义注册到容器中,this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
public <T> void registerBean(@Nullable String beanName, Class<T> beanClass,
@Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {
//ClassDerivedBeanDefinition实现了getPreferredConstructors(),返回公共public的构造器集合
ClassDerivedBeanDefinition beanDefinition = new GenericApplicationContext.ClassDerivedBeanDefinition(beanClass);
if (supplier != null) {
beanDefinition.setInstanceSupplier(supplier);
}
//使用BeanDefinitionCustomizer对beanDefinition进行处理
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(beanDefinition);
}
String nameToUse = (beanName != null ? beanName : beanClass.getName());
//this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
registerBeanDefinition(nameToUse, beanDefinition);
}
}
源码
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
@Nullable
private ResourceLoader resourceLoader;
private boolean customClassLoader = false;
private final AtomicBoolean refreshed = new AtomicBoolean();
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
public GenericApplicationContext(DefaultListableBeanFactory beanFactory) {this.beanFactory = beanFactory; }
public GenericApplicationContext(@Nullable ApplicationContext parent) {
this();
setParent(parent);
}
public GenericApplicationContext(DefaultListableBeanFactory beanFactory, ApplicationContext parent) {
this(beanFactory);
setParent(parent);
}
@Override
public void setParent(@Nullable ApplicationContext parent) {
super.setParent(parent);
this.beanFactory.setParentBeanFactory(getInternalParentBeanFactory());
}
public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) {
this.beanFactory.setAllowBeanDefinitionOverriding(allowBeanDefinitionOverriding);
}
public void setAllowCircularReferences(boolean allowCircularReferences) {
this.beanFactory.setAllowCircularReferences(allowCircularReferences);
}
//---------------------------------------------------------------------
// ResourceLoade处理
//---------------------------------------------------------------------
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public Resource getResource(String location) {
if (this.resourceLoader != null) {
return this.resourceLoader.getResource(location);
}
return super.getResource(location);
}
@Override
public Resource[] getResources(String locationPattern) throws IOException {
if (this.resourceLoader instanceof ResourcePatternResolver) {
return ((ResourcePatternResolver) this.resourceLoader).getResources(locationPattern);
}
return super.getResources(locationPattern);
}
@Override
public void setClassLoader(@Nullable ClassLoader classLoader) {
super.setClassLoader(classLoader);
this.customClassLoader = true;
}
@Override
@Nullable
public ClassLoader getClassLoader() {
if (this.resourceLoader != null && !this.customClassLoader) {
return this.resourceLoader.getClassLoader();
}
return super.getClassLoader();
}
//---------------------------------------------------------------------
// IAbstractApplicationContext抽象方法实现
//---------------------------------------------------------------------
/**
* Do nothing: We hold a single internal BeanFactory and rely on callers
* to register beans through our public methods (or the BeanFactory's).
* @see #registerBeanDefinition
*/
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException();
}
this.beanFactory.setSerializationId(getId());
}
@Override
protected void cancelRefresh(BeansException ex) {
this.beanFactory.setSerializationId(null);
super.cancelRefresh(ex);
}
@Override
protected final void closeBeanFactory() {
this.beanFactory.setSerializationId(null);
}
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
public final DefaultListableBeanFactory getDefaultListableBeanFactory() {
return this.beanFactory;
}
@Override
public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
assertBeanFactoryActive();
return this.beanFactory;
}
//---------------------------------------------------------------------
// 基于this.beanFactory实现BeanDefinitionRegistry方法
//---------------------------------------------------------------------
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
@Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
this.beanFactory.removeBeanDefinition(beanName);
}
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
return this.beanFactory.getBeanDefinition(beanName);
}
@Override
public boolean isBeanNameInUse(String beanName) {
return this.beanFactory.isBeanNameInUse(beanName);
}
@Override
public void registerAlias(String beanName, String alias) {
this.beanFactory.registerAlias(beanName, alias);
}
@Override
public void removeAlias(String alias) {
this.beanFactory.removeAlias(alias);
}
@Override
public boolean isAlias(String beanName) {
return this.beanFactory.isAlias(beanName);
}
//---------------------------------------------------------------------
// 新的注册bean定义的方法
//---------------------------------------------------------------------
public <T> void registerBean(@Nullable String beanName, Class<T> beanClass,
@Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {
ClassDerivedBeanDefinition beanDefinition = new ClassDerivedBeanDefinition(beanClass);
if (supplier != null) {
beanDefinition.setInstanceSupplier(supplier);
}
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(beanDefinition);
}
String nameToUse = (beanName != null ? beanName : beanClass.getName());
registerBeanDefinition(nameToUse, beanDefinition);
}
@SuppressWarnings("serial")
private static class ClassDerivedBeanDefinition extends RootBeanDefinition {
public ClassDerivedBeanDefinition(Class<?> beanClass) {
super(beanClass);
}
public ClassDerivedBeanDefinition(ClassDerivedBeanDefinition original) {
super(original);
}
@Override
@Nullable
public Constructor<?>[] getPreferredConstructors() {
Class<?> clazz = getBeanClass();
Constructor<?> primaryCtor = BeanUtils.findPrimaryConstructor(clazz);
if (primaryCtor != null) {
return new Constructor<?>[] {primaryCtor};
}
Constructor<?>[] publicCtors = clazz.getConstructors();
if (publicCtors.length > 0) {
return publicCtors;
}
return null;
}
@Override
public RootBeanDefinition cloneBeanDefinition() {
return new ClassDerivedBeanDefinition(this);
}
}
}
AnnotationConfigApplicationContext
AnnotationConfigRegistry接口
public interface AnnotationConfigRegistry {
//根据传入组件文件class生成beanDefinition
void register(Class<?>... componentClasses);
//根据传入包名扫描特定注解表示的class生成beanDefinition
void scan(String... basePackages);
}
作用
1、实现了AnnotationConfigRegistry接口的方法
①基于AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner实现
public void register(Class<?>... componentClasses) {
this.reader.register(componentClasses);
}
public void scan(String... basePackages) {
this.scanner.scan(basePackages);
}
2、继承GenericApplicationContext,是注解配置应用上下文的通用接口,使用有两种,一种是指定java组件类(例如添加了@Component),另一种是指定扫描路径
①内部基于两个组件进行实现配置类的注册,会注册对应的bean定义到BeanDefinitionMap,再调用refresh进行容器的刷新
1) AnnotatedBeanDefinitionReader reader:会注册必要的后置处理器,如解析@Configuration,@Autowrite的后置处理类:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等
2) ClassPathBeanDefinitionScanner scanner;
②根据不同的构造方法,使用不同的处理注解配置注册方式
例如指定配置类的时候,其构造方法(核心方法)内的处理如下
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);//AnnotatedBeanDefinitionReader.register方法注册配置类
refresh();//AbstractApplicationContext.refresh刷新容器,容器会基于注册配置类进行处理
}
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this); //this表示BeanDefinitionRegistry,AnnotationConfigApplicationContext基于内部容器实现此接口
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
3、暴露一些方法对这两个组件的属性进行设置,如这种beanName生成器
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
this.reader.setBeanNameGenerator(beanNameGenerator);
this.scanner.setBeanNameGenerator(beanNameGenerator);
getBeanFactory().registerSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
}
AnnotatedBeanDefinitionReader
注册@Configuration,@Autowrite的后置处理类
* 其构造方法中AnnotationConfigUtils.registerAnnotationConfigProcessors
会注册必要的后置处理器,如解析@Configuration,@Autowrite的后置处理类:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等
解析Component类Class成BeanDefinition
* 核心方法 register(Class<?>... componentClasses):开始注册配置类流程
- 使用AnnotatedGenericBeanDefinition来封装参数中指定的配置类
- 设置好abd.setInstanceSupplier(supplier)和abd.setScope(基于@Scope获取,包括scopeName、scopedProxyMode)
- 默认使用AnnotationBeanNameGenerator.generateBeanName获取bean的名称
①取类上的注解@Component || 继承Component|| ManagedBean ||Named的value值,如果为String类型直接返回
②当①返回空时,使用短类名
- 使用AnnotationConfigUtils.processCommonDefinitionAnnotations(abd)解析获取@Lazy、Primary、DependsOn、Role、 Description设置到abd中
- 使用参数中BeanDefinitionCustomizer处理一下abd
- 使用BeanDefinitionHolder封装好abd、beanName
- 使用AnnotationConfigUtils.applyScopedProxyMode进行是否代理的ScopedProxyMode的处理
是话会创建一个代理类的BeanDefinitionHolder,底层封装了原BeanDefinitionHolder
- 注册进入工厂的定义表中,registry.registerBeanDefinition
public class AnnotatedBeanDefinitionReader {
private final BeanDefinitionRegistry registry;
private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
private ConditionEvaluator conditionEvaluator;
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
//context带过来的BeanDefinitionRegistry注册表
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//注册必要的后置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
//核心方法:开始注册配置类
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//先创建BeanDefinition,设置好属性,如beanClass、Scope、Primary、Lazy等
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
//使用BeanDefinitionCustomizer处理一下
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//注册到容器的BeanDefinitionMap
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
}
SpringBoot默认上下文—notationConfigServletWebServerApplicationContext
类图

WebApplicationContext和ConfigurableWebApplicationContext接口
* WebApplicationContext 接口
- 增加一个接口方法ServletContext getServletContext():返回一个web用于上下文,其典型实现类为ApplicationContext,底层基于StandardContext
- 一些常量
* ConfigurableWebApplicationContext接口
- 继承自WebApplicationContext和ConfigurableApplicationContext,提供了web应用上下文的可配置的能力。
- 可配置web应用上下文的ServletContext、ServletConfig、Namespace、上下文的配置文件位置
public interface WebApplicationContext extends ApplicationContext {
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
String SCOPE_REQUEST = "request";
String SCOPE_SESSION = "session";
String SCOPE_APPLICATION = "application";
String SERVLET_CONTEXT_BEAN_NAME = "servletContext";
String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";
String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";
@Nullable
ServletContext getServletContext();
}
public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {
// 设置web应用上下文的ServletContext
void setServletContext(@Nullable ServletContext servletContext);
// 设置/获取web应用上下文的ServletConfig
void setServletConfig(@Nullable ServletConfig servletConfig);
ServletConfig getServletConfig();
// 设置/获取web应用上下文的命名空间,标志当前的web应用上下文
void setNamespace(@Nullable String namespace);
String getNamespace();
// 以初始化参数的形式设置web应用上下文的配置文件位置
void setConfigLocation(String configLocation);
void setConfigLocations(String... configLocations);
String[] getConfigLocations();
}
WebServerApplicationContext和ConfigurableWebServerApplicationContext接口
* WebServerApplicationContext接口
获取一个WebServer服务器对象、服务器对象的命名空间
* ConfigurableWebServerApplicationContext接口
提供服务器对象的命名空间的设置
public interface WebServerApplicationContext extends ApplicationContext {
//获取一个WebServer服务器对象,如内嵌的Tomcat服务器
WebServer getWebServer();
// 获取当前服务器对象的命名空间,即标识
String getServerNamespace();
static boolean hasServerNamespace(ApplicationContext context, String serverNamespace) {
return (context instanceof WebServerApplicationContext) && ObjectUtils
.nullSafeEquals(((WebServerApplicationContext) context).getServerNamespace(), serverNamespace);
}
}
public interface ConfigurableWebServerApplicationContext
extends ConfigurableApplicationContext, WebServerApplicationContext {
//设置当前服务器对象的命名空间,即标识
void setServerNamespace(String serverNamespace);
}
GenericWebApplicationContext
* 作用
继承GenericApplicationContext,在GenericApplicationContext基础上这种一个指定的web应用上下文ServletContext ,以及一些初始化动作
* 设置了一个核心成员ServletContext servletContext表示一个web应用上下文
默认的实现是ApplicationContext类,底层封装了Tomcat的StardardContext
* 重写父类的createEnvironment方法
使用StandardServletEnvironment对象作为容器的环境组件
* 实现容器刷新流程AbstractApplicationContext.refresh中的两个模板方法,对工厂对象进行自定义处理
①postProcessBeanFactory方法,对工厂对象进行自定义处理
- 添加一个bean后置处理器ServletContextAwareProcessor,在bean初始化前postProcessBeforeInitialzation()方法给bean注入当前的servletContext
- 给bean工厂注册scope存储请求属性集合,调用beanFactory.registerScope三个范围的对象Request/Session/appScope(基于底层request/servletContext的attribute变量)
- 在容器注册一些类型的指定依赖类型,如beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory())
- 向容器中注册本类的核心成员ServletContext servletContext以及其相关的信息,交于容器管理
servletContext、servletConfig,contextParameters(ApplicationContext和servletConfig的getInitParameterNames初始配置信息)、contextAttributes(ApplicationContext中getAttributeNames的变量),调用bean工厂的registerSingleton的管理外部对象
if (servletContext != null && !bf.containsBean("servletContext")) {
bf.registerSingleton("servletContext", servletContext);
}
②initPropertySources方法,为prepareRefresh做刷新的准备的第一步,对ConfigurableEnvironment进行PropertySources的初始化设置
基于servletContext.getInitParameterNames()封装了PropertySources
public class GenericWebApplicationContext extends GenericApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
@Nullable
private ServletContext servletContext;
@Nullable
private ThemeSource themeSource;
public GenericWebApplicationContext(DefaultListableBeanFactory beanFactory, ServletContext servletContext) {
super(beanFactory);
this.servletContext = servletContext;
}
//主要处理了ServletContext servletContext的设置
@Override
public void setServletContext(@Nullable ServletContext servletContext) {
this.servletContext = servletContext;
}
public ServletContext getServletContext() {
return this.servletContext;
}
@Override
public String getApplicationName() {
return (this.servletContext != null ? this.servletContext.getContextPath() : "");
}
//创建一个新的ConfigurableEnvironment environment
@Override
protected ConfigurableEnvironment createEnvironment() {
return new StandardServletEnvironment();
}
//实现容器刷新流程中的AbstractApplicationContext.postProcessBeanFactory,对工厂对象进行自定义处理
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.servletContext != null) {
//使用BeanPostProcessor,在bean初始化给bean注入当前的servletContext
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
//给bean工厂注册scope存储,即registerScope
/*
* beanFactory.registerScope(SCOPE_REQUEST, new RequestScope()); 基于底层this.request.getAttribute
beanFactory.registerScope(SCOPE_SESSION, new SessionScope());基于底层this.request.session.getAttribute
beanFactory.registerScope(SCOPE_APPLICATION, appScope);基于底层tthis.servletContext.setAttribute
*
* */
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
//向容器中注册:servletContext、servletConfig(若存在),parameterMap(Application中parameters的变量以及servletConfig:servlet的初始配置信息)
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
//实现容器刷新流程中的AbstractApplicationContext.initPropertySources,对ConfigurableEnvironment进行PropertySources的初始化设置
//基于servletContext.getInitParameterNames()封装了PropertySources
@Override
protected void initPropertySources() {
ConfigurableEnvironment env = getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
}
}
//基于ServletContext.resource作为根目录的资源对象
@Override
protected Resource getResourceByPath(String path) {
Assert.state(this.servletContext != null, "No ServletContext available");
return new ServletContextResource(this.servletContext, path);
}
@Override
protected ResourcePatternResolver getResourcePatternResolver() {
return new ServletContextResourcePatternResolver(this);
}
@Override
protected void onRefresh() {
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}
@Override
@Nullable
public Theme getTheme(String themeName) {
Assert.state(this.themeSource != null, "No ThemeSource available");
return this.themeSource.getTheme(themeName);
}
// ---------------------------------------------------------------------
// 如下方法不实现或者抛出异常
// ---------------------------------------------------------------------
@Override
public void setServletConfig(@Nullable ServletConfig servletConfig) {}
@Override
@Nullable
public ServletConfig getServletConfig() {throw new UnsupportedOperationException();}
@Override
public void setNamespace(@Nullable String namespace) {}
@Override
@Nullable
public String getNamespace() {throw new UnsupportedOperationException();}
@Override
public void setConfigLocation(String configLocation) {
if (StringUtils.hasText(configLocation)) {
throw new UnsupportedOperationException(;
}
}
@Override
public void setConfigLocations(String... configLocations) {
if (!ObjectUtils.isEmpty(configLocations)) {
throw new UnsupportedOperationException();
}
}
@Override
public String[] getConfigLocations() {throw new UnsupportedOperationException();}
//略
}
ServletWebServerApplicationContext
1、继承GenericWebApplicationContext,说明服务器上下文和应用上下文是一一对应,一套的,即时不同ServletWebServerApplicationContext上下文底层可能会使用同一个StandardServer
2、设置了核心变量的 WebServer webServer:表示一个服务器对象,如内嵌的TomcatWebServer服务器对象,底层对应StandardServer,StandardServer会绑定一个StandardService;StandardService会关联Connector、Container,最终关联一个StandardContext
3、设置一个ServletConfig 变量:表示一个servlet配置类,这是一个特殊的servlet对象,是本ServletWebServerApplicationContext内部调用的
4、覆盖了刷新流程AbstractApplicationContext.refresh
当容器刷新失败时,需要关闭创建的webServer.stop()
5、覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法postProcessBeanFactory,
①WebApplicationContextServletContextAwareProcessor(this)会继承GenericWebApplicationContext中的ServletContextAwareProcessor,
所以这里不调用super.postProcessBeanFactory也没关系,会在postProcessBeforeInitialization给bean赋值ServletContext/ServletConfig,
WebApplicationContextServletContextAwareProcessor(this)使得getServletContext/getServletConfig优先从当前类获取,否则取super.getServletContext(),
当前类ServletWebServerApplicationContext this的getServletContext/getServletConfig返回的值,是在onRefresh()阶段启动WebServer赋值的
②registerWebApplicationScopes,注册3个领域的XXXscope对象
*6、(核心实现)覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法,在bean工厂做好准备时候会调用onRefresh抽象模板方法,(步骤在实例化bean之前);这里创建并启动一个完整的WebServer并启动服务器监听
例如返回TomcatWebServer底层对应StandardServer,创建流程如下
①会创建StandardServer绑定一个StandardService,关联新建的Connector、Container
②在新建一个TomcatEmbeddedContext(继承standardContext)作为GenericWebApplicationContext所需的ServletContext ,配置Context的path、DosBae、Loader、valve、MimeMapping、注册ServletContextInitializer(这里会收集ServletContextInitialize类型的对象,例如Aopol配置的文件内容可以在这里进行拉去,并注入到环境对象Eviroment中)、addLifecycleListener、执行customizer.customize(context)等
③Host.addChild(context),执行StandardServer.start()启动服务器,会一路调用到StandardContext.startInternal()
其中Initializer的onStartup是在StandardContext.startInternal()里面执行的,这时就会向Context注册Servlet、Filter、Listener,之后会执行loadOnStartup会载入Servlet
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
private static final Log logger = LogFactory.getLog(ServletWebServerApplicationContextx.class);
public static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet";
//表示一个服务器对象,如内嵌的TomcatWebServer服务器对象,底层对应StandardServer
//StandardServer会绑定一个StandardService
//StandardService会关联Connector、Container,最终关联一个StandardContext
private volatile WebServer webServer;
private ServletConfig servletConfig;
private String serverNamespace;
public ServletWebServerApplicationContextx(DefaultListableBeanFactory beanFactory) {
super(beanFactory);
}
//覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法,
//WebApplicationContextServletContextAwareProcessor会继承GenericWebApplicationContext中的ServletContextAwareProcessor,所以这里不调用super.postProcessBeanFactory也没关系
//WebApplicationContextServletContextAwareProcessor写了其getServletContext/getServletConfig优先从当前类获取
//registerWebApplicationScopes,注册3个领域的XXXscope对象
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
registerWebApplicationScopes();
}
//覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法,
//当容器刷新失败时,需要关闭创建的webServer
@Override
public final void refresh() throws BeansException, IllegalStateException {
try {
super.refresh();
}
catch (RuntimeException ex) {
WebServer webServer = this.webServer;
if (webServer != null) {
webServer.stop();
}
throw ex;
}
}
//覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法,
// bean工厂做好准备时候会调用,这里创建并启动一个完整的WebServer
@Override
protected void onRefresh() {
super.onRefresh();
try {
//创建并启动一个完整的WebServer
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
//如TomcatServletWebServerFactory
ServletWebServerFactory factory = getWebServerFactory();
//例如返回TomcatWebServer底层对应StandardServer
//会创建StandardServer会绑定一个StandardService,关联新建的Connector、Container(直到Engine这一步)
//在新建一个TomcatEmbeddedContext(继承standardContext),配置Context的path、DosBae、Loader、valve、MimeMapping、
//注册ServletContextInitializer、addLifecycleListener、执行customizer.customize(context)等
//最后Host.addChild(context),执行StandardServer.start()
//其中Initializer的onStartup是在StandardContext.startInternal()里面执行的
//这时就会向Context注册Servlet、Filter、Listener,之后会执行loadOnStartup会载入Servlet
this.webServer = factory.getWebServer(getSelfInitializer());
getBeanFactory().registerSingleton("webServerGracefulShutdown",new WebServerGracefulShutdownLifecycle(this.webServer));
getBeanFactory().registerSingleton("webServerStartStop",new WebServerStartStopLifecycle(this, this.webServer));
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();
}
//获取ServletContext初始化器
private ServletContextInitializer getSelfInitializer() {
return this::selfInitialize;
}
//注意,这个方法会作为函数指针传递为TomcatEmbeddedContext
private void selfInitialize(ServletContext servletContext) throws ServletException {
//把servletContext设置到父类的成员中
prepareWebApplicationContext(servletContext);
//创建ServletContextScope
registerApplicationScope(servletContext);
//向容器中注册:servletContext、servletConfig(若存在),parameterMap(ApplicationContext中parameters的变量以及servletConfig:servlet的初始配置信息)
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
//容器中创建中实现了ServletContextInitializer接口的bean,例如ServletRegistrationBean(调用其onStartup向ServletContext中注册Servlet、Filter、Listener)
//容器中创建中Servlet、Filter类型,转为对应的ServletRegistrationBean
//执行所有收集到的ServletContextInitializerBeans的onStartup
for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
beans.onStartup(servletContext);
}
}
@Override
protected Resource getResourceByPath(String path) {
if (getServletContext() == null) {
return new ClassPathContextResource(path, getClassLoader());
}
return new ServletContextResource(getServletContext(), path);
}
@Override
public String getServerNamespace() {
return this.serverNamespace;
}
@Override
public void setServerNamespace(String serverNamespace) {
this.serverNamespace = serverNamespace;
}
@Override
public void setServletConfig(ServletConfig servletConfig) {
this.servletConfig = servletConfig;
}
@Override
public ServletConfig getServletConfig() {
return this.servletConfig;
}
@Override
public WebServer getWebServer() {
return this.webServer;
}
}
AnnotationConfigServletWebServerApplicationContext
* 支持指定注解配置类进行配置的ServletWebServerApplicationContext对象,是Springboot默认创建的上下文
* 覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法postProcessBeanFactory,对工厂对象进行自定义处理
基于AnnotatedBeanDefinitionReader或者ClassPathBeanDefinitionScanner对指定的组件类,封装为BeanDefinition后注册到bean定义表中
* AnnotatedBeanDefinitionReader其构造方法中AnnotationConfigUtils.registerAnnotationConfigProcessors
会注册必要的后置处理器,如解析@Configuration,@Autowrite的后置处理类:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等
* 为reader、scanner设置environment、beanNameGenerator和scopeMetadataResolver
public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext
implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();
private String[] basePackages;
//构造方法
public AnnotationConfigServletWebServerApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory) {
super(beanFactory);
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotationConfigServletWebServerApplicationContext(Class<?>... annotatedClasses) {
this();
//添加进annotatedClasses变量中
register(annotatedClasses);
refresh();
}
public AnnotationConfigServletWebServerApplicationContext(String... basePackages) {
this();
//添加进basePackages变量中
scan(basePackages);
refresh();
}
@Override
protected void prepareRefresh() {
this.scanner.clearCache();
super.prepareRefresh();
}
//使用scanner或者reader
@Override
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()) {
//把配置类的信息封装为对的BeanDefinition后注册到bean定义表中
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
//为reader、scanner设置environment、beanNameGenerator和scopeMetadataResolver
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
super.setEnvironment(environment);
this.reader.setEnvironment(environment);
this.scanner.setEnvironment(environment);
}
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
this.reader.setBeanNameGenerator(beanNameGenerator);
this.scanner.setBeanNameGenerator(beanNameGenerator);
getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
}
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
this.reader.setScopeMetadataResolver(scopeMetadataResolver);
this.scanner.setScopeMetadataResolver(scopeMetadataResolver);
}
//略
}
更多推荐
所有评论(0)