`
m635674608
  • 浏览: 5027055 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

spring的启动过程——spring和springMVC父子容器的原理

 
阅读更多

要想很好理解这三个上下文的关系,需要先熟悉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,事情就简单了,什么麻烦事儿也没有了。

 

 

 

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

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

分享到:
评论

相关推荐

    Spring和SpringMVC父子容器关系

    在Spring与SpringMVC的整合应用中,它们之间存在着一种特殊的父子容器关系,这种关系对于理解和优化应用的配置及管理非常重要。 首先,让我们深入理解Spring容器。Spring容器主要分为两种类型:ApplicationContext...

    Spring和SpringMVC父子容器关系初窥(小结)

    Spring和SpringMVC父子容器关系初窥 Spring和SpringMVC父子容器关系是一个非常重要的概念,在项目中引入Spring和SpringMVC这两个框架时,它们之间存在着父子容器关系。了解这个关系对解决包扫描问题和配置文件的...

    浅谈Spring与SpringMVC父子容器的关系与初始化

    总结起来,Spring与SpringMVC的父子容器关系是Java Web开发中的一种设计模式,它允许开发者将应用程序的不同部分分开管理,提高代码的可维护性和复用性。理解这一关系以及初始化过程对于深入掌握Spring框架和Spring ...

    spring整合springmvc项目

    项目对spring如何整合springmvc进行了详细地注释和介绍,并且包含了很多知识点,比如避免重复扫描包,spring IOC的父子关系和请求筛查等。博客地址:http://blog.csdn.net/qwlzxx/article/details/73732292

    spring的父子容器及配置详解

    总之,Spring的父子容器机制是一种强大的工具,它使得大型项目可以更有序、更灵活地管理Bean的生命周期和依赖关系,有效避免了配置冲突和依赖混乱的问题。在实际开发中,理解并掌握这种机制,能够帮助我们构建更加...

    spring源码合集spring源码合集

    3. **父子容器启动原理**:在"17-SpringMVC源码—父子容器启动原理深入剖析-徐庶"中,我们将揭示Spring MVC如何构建父子容器,并解释容器的启动流程。理解这一过程有助于我们优化应用的初始化性能,合理设计Bean的...

    Spring+SpringMVC配置事务管理无效原因及解决办法详解

    这种情况的原因是 Spring 和 SpringMVC 两个容器为父子关系,Spring 为父容器,而 SpringMVC 为子容器。在 application.xml 中配置的事务管理会被 SpringMVC 重复扫描,导致事务管理无效。 解决办法 要解决 Spring...

    Spring学习笔记系列之三

    本篇我们将聚焦于"Spring学习笔记系列之三"中的关键知识点——SpringMVC的源码分析,特别是父子容器的启动原理。这个主题是理解Spring MVC工作流程、定制化配置以及优化应用程序性能的关键。 首先,我们要明白...

    Spring+SpringMVC+Beetl+Beetlsql+Shiro的开发框架源码

    SpringBlade是一个全面而强大的企业级开发框架,它基于一系列成熟的技术栈,包括Spring、SpringMVC、Beetl、BeetlSQL以及Shiro,旨在简化开发过程,提高开发效率,并提供完整的权限管理功能。下面将分别介绍这些技术...

    关于 SSM 整合.rar

    Spring 和 SpringMVC 是父子容器的关系。Spring 容器是父容器,SpringMVC 是子容器。 子容器可以访问父容器的对象,但是在父容器里不能访问子容器的对象。也就是说在 Controller 里可以访问 Service 对象,但是在 ...

    SpringMVC第一天.pdf

    - **3.2 Spring容器和SpringMVC容器是父子容器:** SpringMVC容器实际上是一个Spring容器的子容器。这意味着: - **3.2.1 SpringMVC容器可以访问父容器(即主Spring容器)中的Bean。** 这种设计使得SpringMVC...

    图灵Java高级互联网架构师第6期源码框架专题笔记.zip

    图灵Java高级互联网架构师第6期源码框架专题笔记,内容包含: 01-Spring底层核心原理解析-周瑜 ...17-SpringMVC源码—父子容器启动原理深入剖析-徐庶 18-MyBatis源码—体系介绍和配置文件解析源码剖析-徐庶 ...

    spring mvc项目

    可用于分析spring mvc源码、spring mvc父子容器初始化流程、session和cookie机制、spring session等,也可以用于学习Java Web(servlet、filter、listener等)、spring源码等。 该项目使用servlet3.0规范,无web.xml...

    maven父子项目(java)+SSM(spring+springmvc+spring-mybatis)+quartz持久化到Oracle数据库

    本人搭的项目,可以正常运行。用于自己存留备份,若有...SSM(spring+springmvc+spring-mybatis)+ quartz持久化到Oracle数据库+ log4j+ Excel处理(只有工具代码,使用代码没放)+ spring-test(测试例子)+ bootstrap

    Java后端日常个人学习笔记

    "17-SpringMVC源码—父子容器启动原理深入剖析-徐庶"这个文件很可能是详细分析了SpringMVC启动过程中的源代码,包括如何初始化容器,如何加载Bean定义,以及如何处理父子容器间的依赖关系。深入理解这部分内容可以...

    springMVC 教程

    双亲上下文(Parent Context)在SpringMVC中扮演着重要的角色,它涉及到Spring应用上下文的父子关系。本教程将讲解如何配置和利用双亲上下文来共享资源。 教程中还包含了对springmvc-mvc.xml配置文件的讲解,这是...

    SpringMVC入门教程

    五、spring mvc 父子上下文的说明 六、springMVC-mvc.xml 配置文件片段讲解 七、spring mvc 如何访问到静态的文件,如jpg,js,css 八、spring mvc 请求如何映射到具体的Action中的方法 九、 spring mvc 中的拦截器:...

    SSM框架整合,maven项目 尚硅谷ssm源码 Spring+SpringMVC+Mybatis+Bootstrap含数据库

    SSM框架整合是Java开发中常见的技术栈,它由Spring、SpringMVC和Mybatis三个核心组件构成,用于构建高效、灵活的企业级Web应用。在这个项目中,还结合了Bootstrap框架,提供了美观的前端界面。下面我们将详细探讨...

    spring培训.pptx

    了解spring的加载机制 beanPostProcessor,beanFactoryPostProcessor 的使用 springmvc 的父子容器 aop切面说明 公司内部培训课件

    国庆SpringBoot相关知识点.docx

    SpringMVC 的 IOC 容器与 Spring 框架的 IOC 容器有父子关系,子容器可以访问父容器,但是父容器不能访问子容器。 六、SpringMVC 的使用步骤 1. 导入相关的包 2. 添加配置文件相关的配置文件(SpringMVC.servlet....

Global site tag (gtag.js) - Google Analytics