前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring如何与Tomcat框架进行集成

Spring如何与Tomcat框架进行集成

作者头像
田维常
发布2019-07-31 11:46:39
2.4K0
发布2019-07-31 11:46:39
举报

一、前言

本节我们讲究如何利用Tomcat的ContextLoaderListener扩展接口来把Spring框架与Tomcat进行连接起来。

二、ContextLoaderListener扩展接口

ContextLoaderListener一般用来启动一个Spring容器或者框架的根容器,例如Webx框架的WebxContextLoaderListener就是继承该类,实现了webx框架到Tomcat容器的衔接点,而SpringMVC则通过在ContextLoaderListener启动一个IOC来管理bo类的bean,下面首先看下ContextLoaderListener的类图结构:

可知ContextLoaderListener的两个方法都是含有一个ServletContextEvent类型的参数。

那么这个ContextLoaderListener一般是怎么使用的那?ContextLoaderListener一般是按照下面的方式配置到web.xml里面:

如上代码,首先创建了一个ContextLoaderListener实例,该实例会创建一个XmlWebApplicationContext应用程序上下文,contextConfigLocation是要告诉ContextLoaderListener要把哪些Bean注入到XmlWebApplicationContext管理的BeanFactory。

这里首先有几个问题,比如配置的全局的contextConfigLocation属性是怎么在ContextLoaderListener中获取的?ContextLoaderListener与Tomcat是什么关系那?ContextLoaderListener是如何创建的XmlWebApplicationContext?

为了解开前两个问题,我们需要看下Tomcat(本文tomcat版本为 apache-tomcat-8.5.12)中的一些代码时序图

  • 在Tomcat中一个StandardContext代表者一个Web应用,时序图中步骤(2)(3)在Web应用启动过程中会调用mergeParameters方法解析web.xml配置的context-param参数,并把这些参数设置到ApplicationContext中,也就是说上面配置的contextConfigLocation参数和值也保存到了ApplicationContext中,需要注意的是这里的ApplicationContext不同于Spring框架中的ApplicationContext,这里的ApplicationContext是tomcat中的ApplicationContext ,它实现了 org.apache.catalina.servlet4preview.ServletContext,是一个ServletContext,这个ApplicationContext是应用级别的,每个应用维护着自己的一个ApplicationContext对象,用来保存应用级别的变量信息,其内部通过 privatefinalConcurrentMap<String,String>parameters=newConcurrentHashMap<>();保存应用级别的变量信息。
  • 时序图中步骤(4)(5)(6)是初始化所有在web.xml里面配置的ServletContextListener的实现类,并以ApplicationContext为构造函数参数创建一个ServletContextEvent 作为ServletContext事件(内部实际维护的是ApplicationContext的一个门面类ApplicationContextFacade),然后调用所有实现类的contextInitialized的方法并传递ServletContextEvent作为参数,至此解开了ContextLoaderListener与Tomcat的关系,也就是说在tomcat的每个应用启动过程中会调用ContextLoaderListener的contextInitialized方法并且传递的参数里面包含该应用级别的一个ApplicationContext对象,该对象里面包含了该应用的全局作用域的变量集合。

下面看下ContextLoaderListener的contextInitialized方法时序图,看是如何创建XmlWebApplicationContext并获取到了contextConfigLocation变量的值作为Spring容器加载Bean的数据源:

  • 如上时序图步骤(3)创建Spring应用程序上下文XmlWebApplicationContext
  • 如上时序图步骤(5)设置XmlWebApplicationContext的ServletContext为ApplicationContextFacade
  • 如上时序图步骤(6)(7)从ServletContext中获取contextConfigLocation变量的值,这里为WEB-INF/applicationContext.xml
  • 如上时序图步骤(8)设置XmlWebApplicationContext的配置文件为WEB-INF/applicationContext.xml,这意味着会从WEB-INF/applicationContext.xml中解析Bean注入到XmlWebApplicationContext管理的BeanFactory。
  • 如上时序图步骤(9)刷新XmlWebApplicationContext应用程序上下文
  • 如上时序图步骤(10)保存XmlWebApplicationContext到ServletContext,这样应用里面任何有ServletContext的地方就可以获取XmlWebApplicationContext,从而可以获取XmlWebApplicationContext管理的所有Bean。

三、 SpringMVC与Tomcat容器的衔接点

SpringMvc是目前使用非常频繁的框架,springmvc里面经常会使用两级级联容器,并且每层容器都各有用途,使用过SpringMVC的童鞋都知道,一般我们在web.xml里面会配置一个listener和一个dispatcher,其实这就配置了两个spring IOC容器,并且dispatcher容器的父容器就是listener的容器。一般在web.xml里面配置如下:

代码语言:javascript
复制
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>
代码语言:javascript
复制
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

其中ContextLoaderListener会创建一个XMLWebApplicationContext上下文来管理contextConfigLocation配置的xml里面的普通bean,这个上节已经讲过。

DispatcherServlet也会创建一个XMLWebApplicationContext默认管理web-info/springmvc-servlet.xml里面的Controller bean,下面看下创建的流程时序图:

如图在DispatcherServlet的初始化方法中首先从ServletContext的全局变量表里面获取ContextLoaderListener创建的XMLWebApplicationContext上下文,然后使用该context作为父上下文创建了SpringMVC的servlet的context容器,并且设置namespace为springmvc-servlet,这个在查找配置文件时候用到,最后会拼接为springmvc-servlet.xml,最后刷新SpringMVC的servlet的context上下文。

一般我们在listener创建的父容器里面配置bo类用来具体操作业务,在dispatcher子容器里面配的Controller类,然后Controller里面具体调用bo类来实现业务。

至此结合上节通过Tomcat启动过程中调用ContextLoaderListener的contextInitialized方法首先创建了父容器用来管理bo bean,然后使用DispatcherServlet创建了子容器用来管理Controller bean ,ContextLoaderListener让SpringMVC与Tomcat容器联系起来了。

四、参考

  • https://docs.spring.io/spring/docs/4.3.13.RELEASE/spring-framework-reference/html/beans.html
  • https://docs.spring.io/spring/docs/4.3.13.RELEASE/spring-framework-reference/html/beans.html#beans-factory-extension
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端技术栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、ContextLoaderListener扩展接口
  • 三、 SpringMVC与Tomcat容器的衔接点
  • 四、参考
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档