org.springframework.web.context.ContextLoaderListener

简介: 在web.xml里面会配置一个listener和一个dispatcher

常用Web框架SpringMVC及WebX级联容器原理探究
一、前言
使用一个东西最好研究下他的原理,因为如果知其然那么在排查问题时候会很方便,本文则针对常用web框架SpringMVC和集团的WebX框架的容器级联关系进行探究。

二、SpringMVC级联容器探究
SpringMvc是目前使用最频繁的框架,springmvc里面经常会使用两级级联容器,并且每层容器都各有用途,本节就来探究下这两层级联容器如何创建。

2.1 配置
使用过SpringMVC的童鞋都知道,一般我们在web.xml里面会配置一个listener和一个dispatcher,其实这就配置了两个spring IOC容器,并且dispatcher容器的父容器就是listener的容器。
一般在web.xml里面配置如下:

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext.xml</param-value>


<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>


其中ContextLoaderListener会创建一个IOC容器使用XMLWebApplicationContext来管理,来管理contextConfigLocation配置的xml里面的bean.
DispatcherServlet也会创建一个IOC容器使用XMLWebApplicationContext管理,默认管理web-info/springmvc-servlet.xml里面的Controller bean。

2.2 ContextLoaderListener创建IOC父容器
image.png

如图属性创建context,然后从servletContext获取在web.xml里面配置的xml文件路径,然后调用spring容器的refresh方法刷新容器解析bean定义,然后把创建好的context放入serlvetcontext的全局变量里面。

2.3 DispatcherServlet 创建子IOC容器
image.png

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

2.4 总结
综合知道一般我们在lisenter创建的父容器里面配置bo类用来具体操作业务,在dispatcher子容器里面配的Controller类,然后Controller里面具体调用bo类来实现业务。

三、WebX级联容器探究
WebX框架在集团曾红火一时,虽然现在已经不主推了,但是其使用子容器隔离不同模块的思想还是很好的 http://www.jianshu.com/p/ff7f5c0ba7db,下面就来探讨下webx是如何创建一父多子级联容器的,

3.1 webx容器结构
引用webx官方文档:
screenshot.png

Webx Framework将一个WEB应用分解成多个小应用模块:app1、app2,当然名字可以任意取。
每个小应用模块独享一个Spring Sub Context子容器。两个子容器之间的beans无法互相注入。
所有小应用模块共享一个Spring Root Context根容器。根容器中的bean可被注入到子容器的bean中;反之不可以。将一个大的应用分解成若干个小应用模块,并使它们的配置文件相对独立,这是一种很不错的开发实践。

3.2 WebX配置结构
image.png

如图是我的一个webx项目的例子,其中webx-business.xml和webx-comm.xml是两个模块分别对应一个sub容器。common下的webx-component.xml是存放每个模块都需要的bean,webx-business.xml和webx-comm.xml都import了该文件。

另外每个webx-模块.xml里面会配置一个component-beans.xml 里面存放该模块需要的bean这些bean其他模块是访问不到的。如何需要配置一些bean需要所以模块都可以访问,那么需要在webx.xml里面配置,因为这里配置的会被放到root容器。

3.3 Root和Sub容器创建
在web项目中引入webx除了需要引入jar包还需要在web.xml配置个listener.

<listener>
    <listener-class>com.alibaba.citrus.webx.context.WebxContextLoaderListener</listener-class>
</listener> 

这个WebxContextLoaderListener类似于SpringMVC中配置的ContextLoaderListener目的就是contextLister主要是创建IOC容器,然后装载/WEB-INF/webx.xml, /WEB-INF/webx-*.xml,好像啊,原来:
image.png

前者继承了后者并且重新了两个方法。

webxlister.png

如图:首先创建了webx的Root 容器上下文 WebxComponentsContext,对应解析webx.xml配置文件,然后调用refresh方法去解析该配置文件里面的bean。下面单独列下spring的容器上下文中refresh内流程,也可以参考 https://www.atatech.org/articles/75912
image.png

上面的refresh会走这个流程,在走这个流程的postProcessBeanFactory阶段会调用WebxComponentsLoader的postProcessBeanFactory方法注册WebxComponentsCreator到Root容器。

然后在invokeBeanFactoryPostProcessors阶段调用WebxComponentsCreator的postProcessBeanFactory创建并初始化子模块,每个模块使用WebxComponentImpl来标示。

然后在finishRefresh阶段会发送Root容器已经刷新OK的事件,会调用WebxComponentsImpl的onApplicationEvent方法。然后会逐个调用子容器的refresh方法根据配置文件webx-*.xml重走一遍流程。

3.4 总结
分析完流程我们回顾下,对于每个模块下的web层的Rpc类的实例和Screen实例和自己的compoment-beans.xml里面的实例是放到自己的模块容器里面的,其他模块是访问不到的。对于需要所有模块都可以访问的bean则配置到webx.xml里面

目录
相关文章
|
15天前
SpringCloud启动Consider defining a bean of type ‘org.springframework.web.client.RestTemplate‘ in your
SpringCloud启动Consider defining a bean of type ‘org.springframework.web.client.RestTemplate‘ in your
7 1
|
5月前
解决:org.springframework.web.method.annotation.MethodArgumentTypeMismatchExceptio
解决:org.springframework.web.method.annotation.MethodArgumentTypeMismatchExceptio
141 0
|
10月前
|
Java 应用服务中间件 Maven
Error configuring application listener of class org.springframework.web.context.ContextLoaderListene
Error configuring application listener of class org.springframework.web.context.ContextLoaderListene
73 0
|
11月前
|
算法 Java API
org.springframework.web.client.HttpClientErrorException: 429 Too Many Requests
org.springframework.web.client.HttpClientErrorException: 429 Too Many Requests
334 0
|
11月前
|
前端开发 Java 应用服务中间件
Error configuring application listener of class org.springframework.web.context.ContextLoader
Error configuring application listener of class org.springframework.web.context.ContextLoader
Error configuring application listener of class org.springframework.web.context.ContextLoader
|
缓存 Java Maven
严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderLis
严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderLis
102 0
严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderLis
|
Java Maven
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener引发的血案
0.看项目中是否部署了Maven Dependencies,如下图,如果没有的话,到pom文件中查看依赖中是否存在标签,如果存在的话删除掉,再重新刷新下项目。这个标签的作用只是声明依赖,并不实现依赖的引入,因此,没有jar包的引入,maven项目就不会显示Maven
96 0
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener引发的血案
|
JSON Dubbo Java
Failed to meta-introspect annotation interface org.springframework.web.bind.annotation.RequestBody:
Failed to meta-introspect annotation interface org.springframework.web.bind.annotation.RequestBody:
222 0
Failed to meta-introspect annotation interface org.springframework.web.bind.annotation.RequestBody:
|
前端开发 Java 应用服务中间件
springMvc49-java.lang.ClassNotFoundException: org.springframework.web.servlet. DispatcherSe
springMvc49-java.lang.ClassNotFoundException: org.springframework.web.servlet. DispatcherSe
112 0
springMvc49-java.lang.ClassNotFoundException: org.springframework.web.servlet. DispatcherSe
|
Java Spring Maven
【web.xml】报错java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
今天搭建新的项目,虽然在web.xml中配置了ContextLoaderListener以及IntrospectorCleanupListener 如下: web.xml中部分代码: 1 2 3 org.
2433 0