Spring-SpringMVC父子容器

转载自  Spring-SpringMVC父子容器

前言

Spring&SpringMVC作为bean管理容器和MVC默认框架,是大多数web应用都会选择的方案。在其使用过程中,尽管基于xml的配置bean管理的方式依然存在,但在很多情况下已经采用的强大的注解功能将其替代。实际项目中,Spring和SpringMVC同时配置,以及xml配置bean和注解的混合使用,会造成诸如bean重复加载、多次实例化、无法自动注入、配置不生效等奇怪的异常现象。其实,以上问题的大多数原因还是出在Spring容器的理解与使用上。

 

容器

Spring整体框架核心概念中,容器是核心思想,但在一个项目,容器不一定只有一个,Spring中可以包括多个容器,且容器间存在上下层框架。最常见的使用场景就是同时使用Spring和SpringMVC两个框架,Srping为父(根)容器,SpringMVC作为子容器。通常的使用过程中,Spring父容器对SpringMVC子容器中的bean是不可见的,而子容器对父容器的中bean却是可见的,这是这两种容器的默认规则。但是:

子容器对父容器中内容可见,不是默认规则

 

加载过程

web容器

对于一个web应用,需要将其部署在web容器中,web容器为其提供一个全局的ServletContext,并作为之后Spring容器提供宿主环境。

Spring根容器

<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

1.web.xml中的contextLoaderListener在web容器启动时,会监听到web容器的初始化事件,其contextInitialized方法会被调用,在这个方法中,spring会初始化一个启动上下文作为根上下文,即WebApplicationContext。WebApplicationContext只是接口类,其实际的实现类是XmlWebApplicationContext。

2.此上下文即作为Spring根容器,其对应的bean定义的配置由web.xml中的context-param中的contextConfigLocation指定。根容器初始化完毕后,Spring以

WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE

为属性Key,将其存储到ServletContext中,便于获取。

SpringMVC子容器

<servlet><servlet-name>XXXX</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
1.contextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,servlet可以配置多个,加载顺序按照load-on-startup来执行。以最常见的DispatcherServlet为例,该servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。DispatcherServlet上下文在初始化的时候会建立自己的上下文,用以持有SpringMVC相关的bean。

2.之后先通过

WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE

先从ServletContext中获取之前的根上下文(即WebApplicationContext)作为自己上下文的父上下文,然后建立DispatcherServlet自己的上下文。这个DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到,内容包括初始化处理器映射、视图解析等。该servlet自己持有的上下文默认实现类也是WebApplicationContext。

3.初始化完毕后,spring以与servlet的名字相关(此处并非简单以servlet名为Key,通过转换码生存)的属性为属性Key,也将其存到ServletContext中,以便后续使用。这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的根上下文中持有的bean。

当然,在根容器创建与子容器创建之间,还会创建监听器、过滤器等,完整的加载顺序为:

ServletContext -> context-param -> listener-> filter -> servlet

由以上过程,即确定了一个bean的使用范围(该使用范围,是比bean的scope定义的singleton、prototype、request、session、global-session的五种作用域更上层的内容)。

 

容器布局

容器布局的根本是确定bean的使用范围。就Spring与SpringMVC布局,也大致分为了两种方向:

传统型

父容器:保存数据源、服务层、DAO层、事务的bean。

子容器:保存MVC相关的controller的bean。

概述:事务控制在服务层。由于父容器不能访问文容器中内容,事务的bean在父容器中,无法访问子容器中内容,就无法对子容器中controller进行AOP(事务),不过做为传统型方案,也没有必要这要做。

激进型

父容器:不关我事~

子容器:管理所有bean。

概述:不使用listener监听器来加载spring的配置文件,只使用DispatcherServlet来加载Spring的配置,不使用父容器,只使用一个DispatcherServlet,抛弃层次概念。

场景:在增删改查为主业务的系统里,Dao层接口,Dao层实现类,Service层接口,Service层实现类,Action父类,Action。再加上众多的O(vo\po\bo)和jsp页面,在满足分层的前提下,做一些相对较小功能时会变得非常冗余,所以“激进型”方案就出现了,没有接口、没有Service层、可以没有众多的O(vo\po\bo),所有事务控制上升到controller层。

关于布局选择吗,引用一句很合景的总结:

大项目求稳,小项目求快。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325918.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务的概念——《微服务设计》读书笔记

《领域驱动设计》&#xff08;Eric Evans&#xff09;&#xff1a;告诉我们用代码呈现真实世界的重要性&#xff0c;并且告诉我们如何更好地建模。 持续交付理论&#xff1a;如何更有效及更高效地发布软件品&#xff0c;并指出保持每次提交均可发布的重要性。 六边形架构理论&a…

图标设计

一、图标的作用&#xff1a; 1.吸引用户的注意力 2.跨语言障碍&#xff0c;更好的实现人机交互。 二、图标的尺寸&#xff1a; 1.128128 2.4848 3.256256 4.3232 5.16*16 三、icon的中文意思就是图标&#xff0c;图形化表示。 四、图标的色彩数量&#xff1a; 1.颜色数&#xf…

React中后台管理系统添加广告分类显示不出来

问题描述 添加广告分类之后&#xff0c;其他的页面能正常显示&#xff0c;看不到广告页面&#xff0c;或者看到广告页面不停的转圈(打开network看到client的拦截信息) 问题分析 可能是浏览器中的拦截器拦截了请求 解决办法 关闭浏览器中的拦截广告插件

自定义机架感知

副本节点的选择&#xff08;机架感知&#xff09; 1、默认情况下 第一个副本在client所处的节点上&#xff0c;如果客户端在集群之外&#xff0c;&#xff08;在win7上运行程序&#xff0c;写文件到集群上&#xff09;&#xff0c;随机选一个。 第二个副本和第一个副本在不同…

想要玩转实现负载均衡,你知道这些吗?

转载自 想要玩转实现负载均衡&#xff0c;你知道这些吗&#xff1f; 一、前言 互联网早期&#xff0c;业务流量比较小并且业务逻辑比较简单&#xff0c;单台服务器便可以满足基本的需求&#xff1b;但随着互联网的发展&#xff0c;业务流量越来越大并且业务逻辑也越来越复杂&…

按钮设计

一、按钮的常识&#xff1a; 1.状态&#xff1a;正常状态、鼠标放上去的状态、按下时的状态 2.按钮的格式&#xff1a;bmp、gif、png、jpg(应用程序中的) gif、png、jpg、swf(网页中的) 二、按钮的表现形式&#xff1a; 1.图形方式 2.文字方式 3.综合方式 4.动画方式 三、按钮的…

netcore实践:跨平台动态加载native组件

缘起netcore框架下实现基于zmq的应用。在.net framework时代&#xff0c;我们进行zmq开发由很多的选择&#xff0c;比较常用的有clrzmq4和NetMQ。 其中clrzmq是基于libzmq的Interop包装&#xff0c; NetMQ是100%C#的zmq实现&#xff08;基于AsyncIO组件&#xff09;。以上两种…

>>右移运算符

>>是右移运算符。假设x5&#xff0c;那么x的二进制为0101&#xff0c;x>>1表示x右移1位&#xff0c;即把最右边一位的1删掉&#xff0c;变为010&#xff0c;此时x2&#xff1b; 仍然设x5&#xff0c;二进制0101&#xff0c;x>>2表示x右移2位&#xff0c;把最…

如何实现酷狗音乐pc页面点击播放时,打开多个歌曲播放时,始终在一个播放页面,(标签页的通讯)

大致有两种思路&#xff0c; 一种是通过wind.open()方法传第二个参数&#xff0c; A页面&#xff1a; //点击跳转播放页函数function toPlayPage(){window.open(path/xxxx/xxxx?name音乐名,music)//第二个参数写一个定值&#xff0c;代表跳转页面都为music标签页&#xff0…

LOGO设计

一、什么是LOGO&#xff1a; 是用一种特殊文字或图像组成的大众传播符号&#xff0c;是人们相互交流的一种视觉语言。 二、LOGO的特征&#xff1a; 1.识别性 2.领导性 3.同一性 4.涵盖性 5.革新性 三、LOGO的格式&#xff1a; 1.为了便于以后更改&#xff1a;ai cdr eps 2.在使…

Redis进阶之内存模型

转载自 Redis进阶之内存模型 前言 Redis是目前最火爆的内存数据库之一&#xff0c;通过在内存中读写数据&#xff0c;大大提高了读写速度&#xff0c;可以说Redis是实现网站高并发不可或缺的一部分。 我们使用Redis时&#xff0c;会接触Redis的5种对象类型&#xff08;字符…

React中jsx的规则

jsx语法规则&#xff1a;1.定义虚拟DOM时&#xff0c;不要写引号。2.标签中混入JS表达式时要用{}。3.样式的类名指定不要用class&#xff0c;要用className。4.内联样式&#xff0c;要用style{{key:value}}的形式去写。5.只有一个根标签6.标签必须闭合7.标签首字母(1).若小写字…

C#将引入可空的引用类型

是的&#xff0c;标题没错。C#其中一份新提案假定&#xff0c;所有的引用类型在默认情况下都是不可空的。在新语法下&#xff0c;你需要显式地标明一个引用变量是可空的&#xff0c;就像对值类型所做的那样。 和值类型一样&#xff0c;T是指不可空类型&#xff0c;而T?是指可…

Android中SlidingDrawer开发报错You need to use a Theme.AppCompat theme (or descendant) with this activity.

Android抽屉开发报错You need to use a Theme.AppCompat theme (or descendant) with this activity. 方法1&#xff1a; 创建的activity时&#xff0c;如果不是那么强烈需要继承自AppCompatActivity&#xff0c;就直接继承Activity。 如将activity继承自AppCompatActivity&…

特效字的设计

一、文字的属性&#xff1a; 1.字体&#xff1a;楷体、宋体、行书、小篆 2.字号&#xff1a;14px 16px 20px 3.颜色&#xff1a;red green 4.特殊属性&#xff1a;文字的粗体和斜体 二、特效字的表现形式 1.文字笔画的变形 2.文字的变化与对比 3.文字的特殊材质 4.综合形式 三、…

Redis进阶之持久化

转载自 Redis进阶之持久化 一、Redis高可用概述 在介绍Redis高可用之前&#xff0c;先说明一下在Redis的语境中高可用的含义。 我们知道&#xff0c;在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&am…

React遍历数组

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>jsx小练习</title> </head> <body><!-- 准备好一个“容器” --><div id"test"></div><!-- 引入rea…

未来的.NET之多重继承

通过抽象接口引入有限形式的多重继承&#xff0c;这一.NET新提议颇具争议性。该特性是受Java默认方法&#xff08;Default Methods&#xff09;的启发。 默认方法的目的在于允许开发人员修改已发布的抽象接口。修改已发布接口将会产生破坏性的更改&#xff0c;因此在Java和.NE…

Android build.gradle(app)介绍

/**首先第一行应用了一个插件&#xff0c;一般有两个值可选&#xff0c;com.android.application表示这是一个应用程序模块&#xff0c;* com.android.library表示这是一个库模块。应用模块和库模块的最大区别是&#xff1a;一个是可以直接运行的&#xff0c;一个只能做为代码库…

React中的方法调用

onClick{demo}//可以调用函数 onClick{demo()}//返回的是undefide