BeanFactory到WebApplicationContext的结构 以及bean和spring容器的关系
BeanFactory: Ioc 容器
ApplicationContext: Spring容器
WebApplicationContext需要ServletContext实例,也就是说它必须在拥有Web 容器的
前提下才能完成启动的工作。
Spring分别提供了用于启动WebApplicationContext的 Servlet和 Web容器监听器: org.springframework.web.context.ContextLoaderServlet;
org.springframework.web.context.ContextLoaderListener。
两者的内部都实现了启动 WebApplicationContext 实例的逻辑,我们只要根据 Web 容
器的具体情况选择两者之一,并在web.xml中完成配置就可以了。
1. 使用 ContextLoader Listener
<!确定配置文件的位置--〉
<context-param>
<param-name>contextConfigLocation</param-name>
<!--此处可以列出多个Spring 的 XML 配置文件→
<param-value>/WEB-INF/daoContext.xml/WEB-iNF/applicationContext.xml</param-value>
</context-param>
<!-- 应用启动时,自动加载listener,该 listener会读取上面确定的XML配置文件。
然后创建ApplicationContext实例--〉
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
ContextLoaderListener 通过 Web 容器上下文参数 contextConfigLocation 获取 Spring 配
置文件的位置。用户可以指定多个配置文件,用逗号、空格或冒号分隔均可。对于未带资
源类型前缀的配置文件路径, WebApplicationContext默认这些路径相对于Web的部署根路
径。当然,我们可以采用带资源类型前缀的路径配置,如classpath:spring/*.xml,classpath:spring/*/*.xml,
和上面的配置是等效的。
2. 使用 ContextLoaderServlet
<servlet>
<!--确定Servlet 的名-->
<servlet-name>context</servlet-name><!--确定 Servlet对应的类--〉
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<!--确定Servlet的启动级别--〉
<load-on-startup>l</load-on-startup></servlet>
采用这种方式时,应将context 的启动级别设成最小,即最优先启动。因为ApplicationContext是整个应用的核心。
注意:在两种启动方式中,推荐采用第一种。因为根据Servlet2.4规范, listener比Servlet优先启动;关键问题是有些容器并不支持Serlet2.4规范,即不支持listener。支持 listener的容器有:
ApacheTomcat4.x 及更高版本。
Jetty4.x及更高版本。
Resin 2.1.8 及更高版本。
Orion2.0.2及更高版本。
BEAWebLogic8.1 SP3
不支持 listener 的容器有:
BEAWebLogicupto 8.1 SP2 及更低版本。
IBMWebSphere 5.x 及更低版本。
OracleOC4J9.0.3 及更低版本。
使用Spring容器以后,程序各元素之间的关系图:
Bean配置信息:定义了Bean的实现和依赖关系。
Spring容器根据 Bean配置信息在容器内部建立Bean注册表。
3.使用ContextLoaderPlugIn
上面我们介绍了WebApplicationContext在Servlet容器中初始化的原理,一般的Web应用就可以轻松的使用了,但是,随着Struts的广泛应用,把Struts和Spring整个起来,是一个需要面对的问题,Spring本身也提供了Struts的相关类,主要使用的有org.springframework.web.struts.ActionSupport,我们只要把自己的Action继承自ActionSupport,就是可以调用ActionSupport中getWebApplicationContext()的方法取出WebApplicationContext,但这样一来在Action中,需要取得业务逻辑的地方都要getBean,看上去不够简洁,所以Spring又提供了另一个方法,用org.springframework.web.struts.ContextLoaderPlugIn,这是一个Struts的Plug,在Struts启动时加载,对于Action,可以像管理Bean一样来管理,在struts-config.xml中Action的配置变成类似下面的样子
<action attribute="aForm" name="aForm" path="/aAction" scope="request" type="org.springframework.web.struts.DelegatingActionProxy">
<forward name="forward" path="forward.jsp" />
</action>
注意type变成了org.springframework.web.struts.DelegatingActionProxy,之后我们需要建立action-servlet.xml这样的文件,action-servlet.xml符合Spring的spring-beans.dtd标准,在里面定义类似下面的
<bean name="/aAction" class="com.web.action.Aaction" singleton="false">
<property name="businessService">
<ref bean="businessService"/>
</property>
</bean>
com.web.action.Aaction是Action的实现类,businessService是需要的业务逻辑,Spring会把businessService注入到Action中,在Action中只要写businessService的get和set方法就可以了,还有一点,action的bean是singleton="false",即每次新建一个实例,这也解决了Struts中Action的线程同步问题,具体过程是当用户做“/aAction”的HTTP请求(当然应该是“/aAction.do”),Struts会找到这个Action的对应类org.springframework.web.struts.DelegatingActionProxy,DelegatingActionProxy是个代理类,它会去找action-servlet.xml文件中“/aAction”对应的真正实现类,然后把它实例化,同时把需要的业务对象注入,然后执行Action的execute方法。
使用了ContextLoaderPlugIn,在struts-config.xml中变成类似这样配置
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml" />
</plug-in>
而在web.xml中不再需要ContextLoaderListener或是ContextLoaderServlet。
说到这里不知道大家会不会有这样的问题,如果使用ContextLoaderPlugIn,如果我们有些程序是脱离Struts的Action环境,我们怎么处理,比如我们要自定义标记库,在标记库中,我们需要调用Spring管理的业务层逻辑对象,这时候我们就很麻烦,因为只有在action中动态注入业务逻辑,其他我们似乎不能取得Spring的WebApplicationContext。
别急,我们还是来看一下ContextLoaderPlugIn的源码(源码不再贴出),我们可以发现,原来ContextLoaderPlugIn仍然是把WebApplicationContext放在ServletContext中,只是这个KEY不太一样了,这个KEY值为ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX+ModuleConfig.getPrefix()(具体请查看源代码),这下好了,我们知道了WebApplicationContext放在哪里,只要我们在Web应用中能够取到ServletContext也就能取到WebApplicationContext了:)
BeanFactory到WebApplicationContext的结构 以及bean和spring容器的关系的更多相关文章
- 7 -- Spring的基本用法 -- 4... 使用 Spring 容器:Spring 容器BeanFactory、ApplicationContext;ApplicationContext 的国际化支持;ApplicationContext 的事件机制;让Bean获取Spring容器;Spring容器中的Bean
7.4 使用 Spring 容器 Spring 有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext 是 BeanFactory ...
- 【Spring学习笔记-3.1】让bean获取spring容器上下文(applicationContext.xml)
*.hl_mark_KMSmartTagPinkImg{background-color:#ffaaff;}*.hl_mark_KMSmartTagBlueImg{background-color:# ...
- spring4.1.8扩展实战之六:注册bean到spring容器(BeanDefinitionRegistryPostProcessor接口)
本章是<spring4.1.8扩展实战>系列的第六篇,目标是学习如何通过自己写代码的方式,向spring容器中注册bean: 原文地址:https://blog.csdn.net/boli ...
- spring boot: spring Aware的目的是为了让Bean获得Spring容器的服务
Spring Aware的目的是为了让Bean获得Spring容器的服务 //获取容器中的bean名称import org.springframework.beans.factory.BeanName ...
- 基于ImportBeanDefinitionRegistrar和FactoryBean动态注入Bean到Spring容器中
基于ImportBeanDefinitionRegistrar和FactoryBean动态注入Bean到Spring容器中 一.背景 二.实现方案 1.基于@ComponentScan注解实现 2.基 ...
- [原创]java WEB学习笔记98:Spring学习---Spring Bean配置及相关细节:如何在配置bean,Spring容器(BeanFactory,ApplicationContext),如何获取bean,属性赋值(属性注入,构造器注入),配置bean细节(字面值,包含特殊字符,引用bean,null值,集合属性list map propert),util 和p 命名空间
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- bean获取Spring容器
Person.java public class Person implements ApplicationContextAware{ private String name; private int ...
- 手动注入bean到spring容器
ApplicationContext applicationContext = SpringContextUtils.getApplicationContext(); //将applicationCo ...
- Spring MVC 了解WebApplicationContext中特殊的bean类型
Spring MVC 了解WebApplicationContext中特殊的bean类型 Spring的DispatcherServlet使用了特殊的bean来处理请求.渲染视图等,这些特定的bean ...
随机推荐
- cpp代码调试,调试扑克牌的代码
#include <iostream> #include <vector> #include <algorithm> using namespace std; cl ...
- BCB:AnsiString BSTR WideString
WideString wstr;AnsiString astr;wchar_t *wp;//或者 BSTR wp; wp=wstr.c_bstr(); //WideString转化为BSTRwstr= ...
- mac层到ath9k层,ath9k层到硬件层
如上图,整个 mac 层分成两个部分——UMAC 和 LMAC.LMAC 分成 MAC 下半部分和硬件抽象层. 硬件抽象层和ath9k层的连接 在hw.h中的函数struct ath_hw_ops() ...
- tcp 高性能服务, netty,mqtt
1. io 线程不要有比较长的服务. 全部异步化. [1] netty 权威指南上只是说业务复杂时派发到业务线程池种. 共用的线程池最好都轻量. 多层线程池后, 下层的可以进行隔离. 这个是 mqtt ...
- 【线性基】bzoj2844: albus就是要第一个出场
线性基求可重rank 题目描述 给定 n 个数 $\{ a_i \}$ ,以及数 $x$. 将 $\{ a_i \}$ 的所有子集(包括空集)的异或值从小到大排序,得到 $\{ b_i \} $. ...
- VIM 编辑器 -使用详解记录
1.什么是 vim? Vim是从 vi 发展出来的一个文本编辑器.代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用.简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但 ...
- Linux下打包解压命令
tar 压缩: tar -cvjpf etc.tar.bz2 /etc //-c为创建一个打包文件,相应的-f后面接创建的文件的名称,使用了.tar.bz2后缀,-j标志使用bzip2压缩,最后面为具 ...
- Voyager下的Dashboard Widgets
widgets设置,voyager.php下找到'widgets': 'widgets' => [ 'TCG\\Voyager\\Widgets\\UserDimmer', 'TCG\\Voya ...
- 《零基础入门学习Python》【第一版】视频课后答案第001讲
测试题答案: 0. Python 是什么类型的语言? Python是脚本语言 脚本语言(Scripting language)是电脑编程语言,因此也能让开发者藉以编写出让电脑听命行事的程序.以简单的方 ...
- 数据结构和算法(What Why How)
数据结构和算法是什么? 从广义上讲,数据结构就是指一组数据的存储结构.算法就是操作数据的一组方法. 从狭义上讲,是指某些著名的数据结构和算法,比如队列.堆.栈.二分查找.动态规划等. 数据结构和算法有 ...