spring-mvc 启动 DispatcherServlet

来看图:

图1

都说DispatcherServlet 是MVC的核心, 从component(一系列adapters, handlers...), context,request生命周期 都是维护在dispatcherServlet中的角度看,是正确的

但是我今天碰到的问题,恰恰与这关系不大

1. 我这边碰到一个问题, project都多个module, 然后在web module中配置了 XXX-servlet.xml中 声明了一组mvc:interceptor, 然后发现这些interceptor 只对web module下的controller 有效, 对于 其他module的controller不能intercept

2. 然后我在web下配置了一个config, 用java的方式把 interceptors注入spring 容器, 去掉XXX-servlet.xml中的mvc:interceptors

图2


结果: 其他module的controller可以intercept,但是web下的不行了。。。。

3. 把mvc:interceptors 配置,移动到application-context.xml中, 然后就可以了, 一切ok了,所有的api都能用了

但是why?什么原因导致的问题。。。。我还没发现

1. 看看web 在启动的init逻辑也许有帮助:

介绍DispatcherServlet机制文章

找到一篇介绍的文章,讲的比较细,上面的图也是从里面来的,文章比较老,现在spring已经有了变化, 但是其中核心的概念不变

DispatcherServlet 说到底是个Servlet,主要任务:

1. 初始化init

2. http请求处理

现在重点来看init, 从而理解我碰到的问题:

图3

init过程的简单流程,如图1

1. 由HttpServletBean.init() 

HttpServletBean.init()

主要是wrap servlet --- 这里主要目的是把servlet 包装成一个标准bean (隐藏不同的细节,同一属性的设置和访问等),具体的实现逻辑可以在研究

然后最重要的就是 initServletBean() 这个方法,会调用FrameworkServlet

2. FrameworkServlet.initServletBean()

包含真正的spring 容器: webApplicationContext, 然后初始化它

FrameworkServlet.initServletBean()

关键在于初始化的WebApplicationContext 有 2 个

2.1. 都知道在web.xml 中一般这么配置:

web.xml(spring 容器)

这里的ContextLoaderListener 将会调用 ContextLoader. initWebApplicationContext 来初始化 ROOT spring 容器

这里提一句,spring的容器context的结构设计 PARENT-CHILD,  CHILD 共享PARENT的bean, CHILD的bean对PARENT不可见

ContextLoader. initWebApplicationContext:

然后调用 createWebApplicationContext, 这里都知道初始化的class 是 XmlWebApplicationContext

然后就是XmlWebApplicationContext 的 loadBeanDefinitions

这里主要就是用reader来load 定义的bean, 在具体:  reader.loadBeanDefinitions

XmlBeanDefinitionReader.loadBeanDefinitions

在具体就在doLoadBeanDefinitions

在register: registerBeanDefinitions

DefaultBeanDefinitionDocumentReader.registerBeanDefinitions

doRegisterBeanDefinitions:

DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions

到这里ROOT的WebApplicationContext 就初始化完了


2.2 web中 servelt mapping: 

这里对应dispatcherServlet 会默认找classpath下的nafweb-servlet.xml,  然后会初始化dispatcherServlet (这才是真正从dispatcherServlet发起的init 初始化的对象), 同样是WebApplicationContext, parent就是上面的ROOT

这里才回到原来的地方:

FrameworkServlet.initServletBean

然后基本都会走到:createWebApplicationContext

FrameworkServlet.createWebApplicationContext

这里的contextClasss 也是XmlWebApplicationContext, 然后是正常的xml读取,解析,生成bean

创建完之后会config: configureAndRefreshWebApplicationContext

之后在initWebApplicationContext 就会 onRefresh(wac); //这里就是DispatcherServlet的初始化 kick-in 

从这里就是一些组件的初始化。。。。后面的就不讲了

总之,处理两个WebApplicationContext之间的关系,最好把大部分bean都放在ROOT中,避免出现我这边出现的问题,是我目前发现的最好的解决办法,至于spring 为什么要搞两个ROOT/CHILD呢?

事实上,spring的设计思想是,隔离所有web相关的bean,最好都在DispatcherServlet中,然后ROOT中放一些共用的,基础的bean,但是在实现的时候,因为模块的问题,一些controller被放到分散的模块中,然后在引入xml文档的时候都是在application-context-web.xml中import resource 导致这部分controller 被 注入到ROOT Context中, 那么正确的方式是咋样?

1. 应该把controller的扫描xml 分开, 单独扫描, 比如<context:component-scan base-package="com.XXX.controller" /> 不要直接到com.XXX

然后把这个定义 放到单独的xml中

2. 把这个xml 在XXX-servlet.xml中import

就能解决这次碰到的问题了

PS: 所有spring代码基于最新的spring master  (spring5)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容