1. 首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境;
  2. 其次,在web.xml中会提供有contextLoaderListener。在web容器启动时,会触发容器初始化事件,此时contextLoaderListener会监听到这个事件,其contextInitialized方法会被调用,在这个方法中,spring会初始化一个启动上下文,这个上下文被称为根上下文,即WebApplicationContext,这是一个接口类,确切的说,其实际的实现类是XmlWebApplicationContext。这个就是spring的IoC容器,其对应的Bean定义的配置由web.xml中的context-param标签指定。在这个IoC容器初始化完毕后,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取;
  3. 再次,contextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,这个servlet可以配置多个,以最常见的DispatcherServlet为例,这个servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。DispatcherServlet上下文在初始化的时候会建立自己的IoC上下文,用以持有spring mvc相关的bean。在建立DispatcherServlet自己的IoC上下文时,会利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先从ServletContext中获取之前的根上下文(即__WebApplicationContext)作为自己上下文的__parent__上下文。有了这个__parent__上下文之后,再初始化自己持有的上下文。这个__DispatcherServlet__初始化自己上下文的工作在其__initStrategies__方法中可以看到,大概的工作就是初始化处理器映射、视图解析等。这个__servlet__自己持有的上下文默认实现类也是__mlWebApplicationContext。初始化完毕后,spring__以与__servlet__的名字相关(此处不是简单的以__servlet__名为__Key,而是通过一些转换,具体可自行查看源码_)的属性为属性__Key,也将其存到__ServletContext__中,以便后续使用。这样每个__servlet__就持有自己的上下文,即拥有自己独立的__bean__空间,同时各个__servlet__共享相同的__bean__,即根上下文__(_第__2__步中初始化的上下文)定义的那些bean。

使用listener监听器来加载配置文件,如下:

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

Spring 会创建一个WebApplicationContext上下文,称为父上下文(父容器),保存在 ServletContext中,key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。

可以使用Spring提供的工具类取出上下文对象:WebApplicationContextUtils.getWebApplicationContext(ServletContext);

子上下文:

使用Spring MVC 来处理拦截相关的请求时,会配置DispatchServlet

<servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/applicationContext-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

每个DispatchServlet会有一个自己的上下文,称为子上下文,它也保存在 ServletContext中,key 是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名称。当一 个Request对象产生时,会把这个子上下文对象(WebApplicationContext)保存在Request对象中,key是 DispatcherServlet.class.getName() + ".CONTEXT"。

可以使用工具类取出上下文对象:RequestContextUtils.getWebApplicationContext(request);

父上下文(父容器)和子上下文(子容器)的访问权限:

子上下文可以访问父上下文中的bean,但是父上下文不可以访问子上下文中的****bean。

父上下文使用与否

方案一,传统型:

父上下文容器中保存数据源、服务层、DAO层、事务的Bean。

子上下文容器中保存Mvc相关的Action的Bean.

事务控制在服务层。

由于父上下文容器不能访问子上下文容器中内容,事务的Bean在父上下文容器中,无法访问子上下文容器中内容,就无法对子上下文容器中Action进行AOP(事务)。

当然,做为“传统型”方案,也没有必要这要做。

方案二,激进型:

Java世界的“面向接口编程”的思想是正确的,但在增删改查为主业务的系统里,Dao层接口,Dao层实现类,Service层接口,Service层实现类,Action父类,Action。再加上众多的O(vo\po\bo)和jsp页面。写一个小功能 7、8个类就写出来了。

开发者说我就是想接点私活儿,和PHP,ASP抢抢饭碗,但我又是Java程序员。最好的结果是大项目能做好,小项目能做快。所以“激进型”方案就出现了-----没有接口、没有Service层、还可以没有众多的O(vo\po\bo)。那没有Service层事务控制在哪一层?只好上升的Action层。

本文不想说这是不是正确的思想,我想说的是Spring不会限制你这样做。

由于有了父子上下文,你将无法实现这一目标。解决方案是只使用子上下文容器,不要父上下文容器 。所以数据源、服务层、DAO层、事务的Bean、Action的Bean都放在子上下文容器中。就可以实现了,事务(注解事务)就正常工作了。这样才够激进。

总结:不使用listener监听器来加载spring的配置文件,只使用DispatcherServlet来加载spring的配置,不要父子上下文,只使用一个DispatcherServlet,事情就简单了,什么麻烦事儿也没有了。

Java--大项目能做好--按传统方式做,规规矩矩的做,好扩展,好维护。

Java--小项目能做快--按激进方式做,一周时间就可以出一个版本,先上线接受市场(用户)的反馈,再改进,再反馈,时间就是生命(成本)。

Spring和springMVC父子容器的原理相关推荐

  1. Spring和SpringMVC父子容器关系初窥

    一.背景 最近由于项目的包扫描出现了问题,在解决问题的过程中,偶然发现了Spring和SpringMVC是有父子容器关系的,而且正是因为这个才往往会出现包扫描的问题,我们在此来分析和理解Spring和 ...

  2. 探究Spring和SpringMVC父子容器关系

    兄弟萌,相信有很多人想不到 Spring 和 SpringMVC 是父子容器吧,^ - ^,下面我们来一探究竟. 一般做 SSM 框架项目时,扫描 @Controller 注解类的对象是在 Sprin ...

  3. 面试高频题:Spring和SpringMvc父子容器你能说清楚吗

    引言 以前写了几篇关于SpringBoot的文章<面试高频题:springBoot自动装配的原理你能说出来吗>.<保姆级教程,手把手教你实现一个SpringBoot的starter& ...

  4. Spring系列:父子容器详解

    又一次被面试官带到坑里面了. 面试官:springmvc用过么? 我:用过啊,经常用呢 面试官:springmvc中为什么需要用父子容器? 我:嗯...没听明白你说的什么. 面试官:就是control ...

  5. Spring MVC上下文父子容器

    2019独角兽企业重金招聘Python工程师标准>>> Spring MVC上下文父子容器 博客分类: java spring 在Spring MVC的启动依赖Spring框架,有时 ...

  6. boot spring 没有父子容器_Spring 系列(二):Spring MVC的父子容器

    1.背景 在使用Spring MVC时候大部分同学都会定义两个配置文件,一个是Spring的配置文件spring.xml,另一个是Spring MVC的配置文件spring-mvc.xml. 在这里给 ...

  7. 【Spring(八)】父子容器

    Spring的容器具可以具有父子关系.具体含义就是:如果两个容器具有父子关系,那么在查找bean时,会先从子容器中查找,如果没有就查找父容器.但是父容器不能查找子容器的bean. 这个特性有什么意义? ...

  8. Spring第24篇:父子容器详解

    主要的问题 1. 什么是父子容器? 2. 为什么需要用父子容器? 3. 父子容器如何使用? 下面我们就来探讨探讨. 我们先来看一个案例 系统中有2个模块:module1和module2,两个模块是独立 ...

  9. Spring和SpringMVC的父子容器关系

    容器 在Spring整体框架的核心概念中,容器是核心思想 就是用来管理Bean的整个生命周期的 在一个项目中,容器不一定只有一个 Spring中可以包括多个容器,而且,容器有上下层关系 一个项目中引入 ...

最新文章

  1. Linux Shell简介
  2. 2.0-zabbix配置邮件告警
  3. pytorch和Numpy的区别以及相互转换
  4. 整整4个月了,尽全力组织了源码共读活动~
  5. 路由删除命令_清除思科路由器配置信息的两种方法
  6. SAP License:发票校验
  7. 【直通BAT】剑指Offer 经典试题整理(5)
  8. grep的-A-B-选项详解(转)
  9. 有一种努力叫“凌晨四点”
  10. 读取pdf文字和excel写入操作
  11. Java(等级划分)
  12. 利用Python进行数据分析之超市零售分析
  13. Google-Guava(Utilites)
  14. Omnipeek空口抓包(2):扫描无线网络
  15. 静态工具类使用单例对象线程安全问题注意1
  16. 五子棋AI图形界面人机对战(JAVA实现)
  17. each函数linux,each的详解
  18. flexsim仿真模型-MC公司下游仓库管理仿真实验
  19. iscroll.js移动端滚动插件
  20. App合规讲堂 (四)-APP是否逐一列出APP及第三方代码收集使用个人信息的目的、方式、范围等

热门文章

  1. HDU5686 Problem B【递推】
  2. 软件开发 —— 极限编程(XP:Extreme Programming)
  3. matplotlib 可视化 —— matplotlib.patches
  4. python 一题多解 —— ndarray 一维数组的拼接
  5. 组合数的研究 —— 连续整数的配对
  6. utilities(matlab)—— minFunc
  7. 深度学习基础(二)—— 从多层感知机(MLP)到卷积神经网络(CNN)
  8. utilities(C++)——单例(Singleton)
  9. 被平均(统计平均)的陷阱
  10. 中点坐标公式 矩形_2019南充第16题——平面直角坐标系、矩形、K字型相似、运动与最值...