SpringBoot具体创建哪种ApplicationContext和WebApplicationType有关:

public enum WebApplicationType {
	/**
         * 非web应用,没有内嵌tomcat
	 * The application should not run as a web application and should not start an
	 * embedded web server.
	 */
	NONE,

	/**
	 * web应用,启动内嵌tomcat 
         * The application should run as a servlet-based web application and should start an
	 * embedded servlet web server.
	 */
	SERVLET,

	/**
	 * The application should run as a reactive web application and should start an
	 * embedded reactive web server.
	 */
	REACTIVE;
复制代码

在传统的Tomcat容器打包应用的情况下,Tomcat根据web.xml初始化ServletContext后回调ContextLoaderListener,默认创建的Context(见ContextLoader.properties配置)为XmlWebApplicationContext。

 

 

 

先看下ApplicationContext能干啥

An ApplicationContext provides:

  • Bean factory methods for accessing application components.
  • The ability to load file resources in a generic fashion.
  • The ability to publish events to registered listeners.
  • The ability to resolve messages, supporting internationalization.
  • Inheritance from a parent context. Definitions in a descendant context will always take priority. This means, for example, that a single parent context can be used by an entire web application, while each servlet has its own child context that is independent of that of any other servlet.

ApplicationContext创建时指定parent继承(顶层为null),有点类似类的双亲加载,如果子Context找不到Bean,则向上追溯,如果找到,即在父Context的自治环境(BeanFactory)内实现Bean初始化等一系列操作,父Context初始化的Bean只能使用自身BeanFactory里的BeanPostProcessor等这些自身环境内的加强处理(它根本不知道谁继承了自己)。

无论哪种ApplicationContext都能在类图的某个节点找到属性BeanFactory,该Context加载的BeanDefinition和生成的单例Bean即存在于此,可ApplicationContext为啥也实现了BeanFactory接口?答:通过ApplicationContext向外暴***ean,BeanFactory是内部具体实现。

拿一个普通的SpringBootApplication来说,启动时会有一个全局的ApplicationContext(传统的springmvc应用可见applicationContext.xml),而为了处理WebRequest,至少会启动一个DispatchServlet(继承自FrameworkServlet),DispatchServlet会有自己的ApplicationContext(传统springmvc应用可见dispatch-servlet.xml),这个Conext继承了前面的全局ApplicationContext。

如果没有注意到这种Context继承关系和封闭性,举个遇到过的老应用开发时碰到过的问题,全局Context的BeanPostProcessor应用不到dispatch-servlet.xml创建的bean里面,导致出现了某些问题。

Context是一个封闭上下文,有自己的命名空间(BeanFactory),有自己的Environment配置,还有注册到自身的ApplicationListener等,保证影响限制在一个区域里面,互相不污染,也保障了安全。

就酱。