spring父子容器

2023-05-16

https://www.jb51.net/article/132197.htm

http://www.cnblogs.com/kevin-yuan/p/6404702.html

https://blog.csdn.net/user_xiangpeng/article/details/52181710

 

要想很好理解这三个上下文的关系,需要先熟悉spring是怎样在web容器中启动起来的。spring的启动过程其实就是其IoC容器的启动过程,对于web程序,IoC容器启动过程即是建立上下文的过程。

spring的启动过程:

  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。

说完了spring上下文的初始化过程,这三个上下文的关系应该就了解了。如还是不太清楚,我就爱莫能助了,只能自行看代码去了。

===============================================================================================================

 

最近在做项目时牵扯到有关父子上下文的概念。

何为父子上下文呢?

父上下文:

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

?

1

2

3

<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:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<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,事情就简单了,什么麻烦事儿也没有了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring父子容器 的相关文章

  • 面试题集锦-JVM

    JVM 1 说一下 JVM 的主要组成部分 xff1f 及其作用 xff1f 2 说一下 JVM 运行时数据区 xff1f 3 说一下堆栈的区别 xff1f 4 队列和栈是什么 xff1f 有什么区别 xff1f 5 什么是双亲委派模型 x
  • eclipse快捷键

    ctrl 43 t 查看接口实现类 ctrl 43 shif 43 t 快速查找某个类 包括jar中类 ctrl 43 shift 43 r 快速查找工作空间中项目的类
  • short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?

    答 xff1a 对于short s1 61 1 s1 61 s1 43 1 由于1是int类型 xff0c 因此s1 43 1运算结果也是int 型 xff0c 需要强制转换类型才能赋值给short型 而short s1 61 1 s1 4
  • int和Integer有什么区别

    答 xff1a Java是一个近乎纯洁的面向对象编程语言 xff0c 但是为了编程的方便还是引入了基本数据类型 xff0c 但是为了能够将这些基本数据类型当成对象操作 xff0c Java为每一个基本数据类型都引入了对应的包装类型 xff0
  • Java 中 Equals和==的区别

    在谈论equals和 61 61 的区别前 xff0c 我们先简单介绍一下JVM中内存分配的问题 在JVM中 内存分为栈内存和堆内存 二者有什么区别呢 xff1f 当我们创建一个对象 xff08 new Object xff09 时 xff
  • 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

    答 xff1a 是值传递 Java语言的方法调用只支持参数的值传递 当一个对象实例作为一个参数被传递到方法中时 xff0c 参数的值就是对该对象的引用 对象的属性可以在被调用过程中被改变 xff0c 但对对象引用的改变是不会影响到调用者的
  • 什么情况下用+运算符进行字符串连接比调用StringBuilder对象的append方法连接字符串性能更好?

    经常在网上看到或者在周围听到有人说字符串拼接不要直接用 String 相加 xff0c StringBuilder 的效率要比 String 直接相加拼接要高 还有人常说 xff0c StringBuffer 是同步的 xff08 线程安全
  • 解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法。

    答 xff1a 通常我们定义一个基本数据类型的变量 xff0c 一个对象的引用 xff0c 还有就是函数调用的现场保存都使用内存中的栈空间 xff1b 而通过new关键字和构造器创建的对象放在堆空间 xff1b 程序中的字面量 xff08
  • Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?

    Math round 11 5 的返回值是12 xff0c Math round 11 5 的返回值是 11 四舍五入的原理是在参数上加0 5然后进行下取整 所谓向上取整指当计算的结果不为整数时取大于计算结果的整数 向下取整指当计算的结果不
  • Spring注入详解

    注入方式 构造函数注入 public class UserServiceImpl implents UserService private UserDao userDao 64 Autowire public UserServiceImpl
  • yml文件

    YAML文件简介 我们可能在spring配置文件里见到过 yml格式的东东 xff0c 配置文件不都是 propertie或者 xml文件吗 xff1f yml是什么鬼 xff0c 今天我带你们来一探究竟 YAML xff08 Yet An
  • YAML 语言教程

    作者 xff1a 阮一峰 日期 xff1a 2016年7月 4日 编程免不了要写配置文件 xff0c 怎么写配置也是一门学问 YAML 是专门用来写配置文件的语言 xff0c 非常简洁和强大 xff0c 远比 JSON 格式方便 本文介绍
  • 如何解决idea的Could not autowire. No beans of 'xxxx' type found

    打开设置setting 在左侧找到Editor xff0c 然后选择 Inspections 在右侧的搜索框下面 xff0c 找到SPRING那块 xff0c 然后找到spring的核心包 xff0c 选中spring core 找到cod
  • IntelliJ IDEA中绿色注释扫描飘红报错解决

    在IDEA中的setting中搜索 34 javadoc 34 基本上 xff0c 绿色注释飘红的问题是解决了 xff1b
  • Windows10在当前目录快速打开cmd的方法

    1 按住Shift键 xff0c 鼠标右键快捷方式 xff0c 先打开Powershell窗口 2 输入 start cmd 回车 3 这样就可以打开cmd窗口了 xff0c 并且cmd的工作目录就是当前的目录
  • marvn 环境变量配置

    1 首先下载maven xff0c 下载地址 xff1a http maven apache org download html 打开这个连接 xff1a 选择File下面的apache maven 3 2 1 bin zip链接进行下载
  • mvn命令

    在pom xml目录下 打开cmd xff0c 输入mvn命令 1 mvn dependency tree 打印项目的依赖树到控制台 mvn dependency tree gt gt D tree txt 导出依赖树到指定文件 2 mvn
  • cmd命令

    1 创建多级目录 md mkdir 目录1 目录2 目录3 C Users xxx gt pushd d D gt md 1 2 3 4 D gt pushd D 1 2 3 4 D 1 2 3 4 gt 2 pushd POPD push
  • css浏览器兼容问题

    1 CSS中几种浏览器对不同关键字的支持 xff0c 可进行浏览器兼容性重复定义 important 可被FireFox和IE7识别 可被IE6 IE7识别 可被IE6识别 43 可被IE7识别 区别IE6与FF xff1a backgro
  • mybatis annotations

    1 Alias别名 64 Documented 64 Retention RetentionPolicy RUNTIME 64 Target ElementType TYPE public 64 interface Alias String

随机推荐

  • Python+Flask实现股价查询系统。Python绘制股票k线走势

    文章目录 一 实现效果图二 实现思路1 获取数据 2 可视化数据三 源码获取 一 实现效果图 打开默认显示半年线 xff0c 可以通过可视化类型选择可视化k线图 高低点等 xff08 目前只完成了初版 xff0c 当查询的股票数据返回为空时
  • typeHandlers 类型处理器

    类型转换器官网地址 无论是 MyBatis 在预处理语句 xff08 PreparedStatement xff09 中设置一个参数时 xff0c 还是从结果集中取出一个值时 xff0c 都会用类型处理器将获取的值以合适的方式转换成 Jav
  • idea创建父子工程

    new 一个project xff0c 删除src xff0c 只保留pom文件 xff0c 作为主工程 webparent xff0c 工程目录D ideaProjects self multimodule xff1b 右键点击上面创建的
  • css基础

    层叠次序 当同一个 HTML 元素被不止一个样式定义时 xff0c 会使用哪个样式呢 xff1f 一般而言 xff0c 所有的样式会根据下面的规则层叠于一个新的虚拟样式表中 xff0c 其中数字 4 拥有最高的优先权 浏览器缺省设置外部样式
  • spring官网下载jar包

    http repo spring io release org springframework spring 查找方法 xff1a https spring io gt 点击 project https spring io projects
  • idea快捷键

    Intellij IDEA神器居然还藏着这些实用小技巧 xff0c 爽 xff01 xff01 xff01 自动补全返回值 可以引入变量 ctrl 43 alt 43 v Ctrl 43 或者 xff0c 可以跑到大括号的开头与结尾 Ctr
  • IDEA添加serialVersionUID

    打开IDEA中的 Setting gt Editor gt Inspections 选项中 xff0c java gt Serialization issues gt 将Serializable class without 39 seria
  • java序列化

    http www cnblogs com szlbm p 5504166 html Java对象表示方式1 xff1a 序列化 反序列化和transient关键字的作用 平时我们在Java内存中的对象 xff0c 是无 法进行IO操作或者网
  • Java之Collections.emptyList()、emptySet()、emptyMap()的作用和好处以及要注意的地方。

    https blog csdn net qq 27093465 article details 65444622 先说明一下好处有哪些 xff1a 1 xff0c 如果你想 new 一个空的 List xff0c 而这个 List 以后也不
  • java String ... valuese 什么意思

    jdk1 5的新特性 xff1a 变长变量 其实这种定义就类似一个数据的定义 xff0c 可以不用给它的长度加以限制 xff0c 可以传入任意多个参数 比用数据更灵活一些 xff0c 不会出现一些数组越界等的异常 如 xff1a getTy
  • debug技巧和使用

    介绍一种能debug到HashMap内部数据结构的方法 https blog csdn net victor cindy1 article details 52336983 1 这里以一个web工程为例 xff0c 点击图中按钮开始运行we
  • Linux中如何添加/删除FTP用户并设置权限?

    以阿里云服务器为例 xff0c 在linux中添加ftp用户 xff0c 并设置相应的权限 xff0c 操作步骤如下 xff1a 1 环境 xff1a ftp为vsftp 被设置用户名为test 被限制路径为 alidata www tes
  • 解析IOS二进制格式的bplist

    关于二进制格式的plist xff0c 搜到一篇博客 详解Binary Plist格式 xff0c 介绍的很详细 xff0c 但是结合github上关于一份解析bplist的代码通过结果实际来看 xff0c 博客中解析对象表的说明出现了问题
  • Java中的String,StringBuilder,StringBuffer三者的区别

    最近在学习Java的时候 xff0c 遇到了这样一个问题 xff0c 就是String StringBuilder以及StringBuffer这三个类之间有什么区别呢 xff0c 自己从网上搜索了一些资料 xff0c 有所了解了之后在这里整
  • SynthesizedAnnotation

    标识组合注解 该接口没有实现类 xff0c 具体用法待研究
  • autowire注解源码解析

    引用 xff1a https blog csdn net wang704987562 article details 80868368
  • ConcurrentHashMap解析

    https www cnblogs com ITtangtang p 3948786 html java util concurrent xff08 j u c xff09 源码阅读
  • Java中getResourceAsStream的用法

    https www cnblogs com macwhirr p 8116583 html 首先 xff0c Java中的getResourceAsStream有以下几种 xff1a 1 Class getResourceAsStream
  • Map var2 = this.bfgInstancesByKey; synchronized(this.bfgInstancesByKey) { 疑惑

    org springframework beans factory access SingletonBeanFactoryLocator useBeanFactory public BeanFactoryReference useBeanF
  • spring父子容器

    https www jb51 net article 132197 htm http www cnblogs com kevin yuan p 6404702 html https blog csdn net user xiangpeng