本文共 2150 字,大约阅读时间需要 7 分钟。
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:
ApplicationContext创建时指定parent继承(顶层为null),有点类似类的双亲加载,如果子Context找不到Bean,则向上追溯,如果找到,即在父Context的自治环境(BeanFactory)内实现Bean初始化等一系列操作,父Context初始化的Bean只能使用自身BeanFactory里的BeanPostProcessor等这些自身环境内的加强处理(它根本不知道谁继承了自己)。
无论哪种ApplicationContext都能在类图的某个节点找到属性BeanFactory,该Context加载的BeanDefinition和生成的单例Bean即存在于此,可ApplicationContext为啥也实现了BeanFactory接口?答:通过ApplicationContext向外暴露Bean,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等,保证影响限制在一个区域里面,互相不污染,也保障了安全。
就酱。
转载地址:http://kyfvi.baihongyu.com/