Spring容器ApplicationContext实现和配置WebApplicationContext

来源:互联网 发布:怎么禁用135端口 编辑:程序博客网 时间:2024/06/06 12:57
ApplicationContext 是 BeanFactory 接口的子接口,它增强了 BeanFactory 的功能,处于 context 包下。很多时候, ApplicationContext 允许以声明式方式操作容器,
无须手动创建。可利用如 ContextLoader 的支持类,在 Web 应用启动时自动创建 ApplicationContext。当然,也可以采用编程方式创建 ApplicationContext。

ApplicationContext包括BeanFactory的全部功能,因此建议优先使用ApplicationContext。除非对于某些内存非常关键的应用,才考虑使用 BeanFactory。


spring为ApplicationContext提供的3种实现分别为:


1、  ClassPathXmlApplicationContext:利用类路径的XML文件来载入Bean定义的信息


[1]  ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");


[2]  String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};


ApplicationContext ctx = new ClassPathXmlApplication(locations);


2、 FileSystemXmlApplicationContext:利用文件系统中的XMl文件来载入Bean


定义的信息


[1]  ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml"); //加载单个配置文件


[2]  String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};


 ApplicationContext ctx = new FileSystemXmlApplicationContext(locations );//加载多个配置文件


[3]  ApplicationContext ctx =new FileSystemXmlApplicationContext("D:/project/bean.xml");//根据具体路径加载




3、XmlWebApplicationContext:从Web系统中的XML文件来载入Bean定义的信息。


 ServletContext servletContext = request.getSession().getServletContext();    


 ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

 
4.与BeanFactory通常以编程的方式被创建不同的是,ApplicationContext能以声明的方式创建,如使用ContextLoader。
当然你也可以使用ApplicationContext的实现之一来以编程的方式创建ApplicationContext实例。首先,让我们先分析ContextLoader接口及其实现。


ContextLoader接口有两个实现:ContextLoaderListener和ContextLoaderServlet。两者都实现同样的功能,但不同的是,
ContextLoaderListener不能在与Servlet 2.2兼容的web容器中使用。根据Servlet 2.4规范, servlet context listener要在web应用程序的servlet context建立后立即执行,
并要能够响应第一个请求(在servlet context要关闭时也一样):这样一个servlet context listener是初始化spring ApplicationContext的理想场所。
虽然使用哪个完全取决于你,但是在同等条件下应该首选ContextLoaderListener;对于更多兼容性的信息,请查看ContextLoaderServlet的JavaDoc。



5.配置WebApplicationContext的两种方法:


(1)利用Listener接口来实现


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


<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext</param-value>
</context-param>


(2)利用Servlet接口来实现


<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext</param-value>
</context-param>


<Servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>
        org.springframework.web.context.ContextLoaderServlet
    </servlet-class>
<init-param>  
<param-name>contextConfigLocation</param-name>  
<param-value>classpath*:/spring/config/applicationContextMVC.xml</param-value>  
</init-param> 
</servlet>


监听器首先检查contextConfigLocation参数,如果它不存在,它将使用/WEB-INF/applicationContext.xml作为默认值。
如果已存在,它将使用分隔符(逗号、冒号或空格)将字符串分解成应用上下文将位置路径。
ContextLoaderServlet同ContextLoaderListener一样使用'contextConfigLocation'参数。


6.listener和Servlet区别:
ContextLoaderListener中加载的context成功后,spring 将 applicationContext存放在ServletContext中key值为"org.springframework.web.context.WebApplicationContext.ROOT"的attribute中。
(servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context));
可以通过WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)或
WebApplicationContextUtils.getWebApplicationContext(servletContext)方法来获取对应的applicationContext。


DispatcherServlet加载的context成功后,如果 publishContext属性的值设置为true的话(缺省为true) 会将applicationContext
存放在org.springframework.web.servlet.FrameworkServlet.CONTEXT. + (servletName)的attribute中。
则对应的applicationContext的attribute key值为org.springframework.web.servlet.FrameworkServlet.CONTEXT.mvcServlet。


在每次request请求时,DispatcherServlet会将此applicationContext存放在request中attribute值为 org.springframework.web.servlet.DispatcherServlet.CONTEXT中(request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE,getWebApplicationContext());)。
可以通过 RequestContextUtils.getWebApplicationContext 或 WebApplicationContextUtils.getWebApplicationContext(servletContext,attrname)方法 来获取对应的applicationContext。


从上面的分析可以看出,DispatcherServlet所加载的applicationContext可以认为是mvc私有的context,由于保存在servletContext中的key值与
通过ContextLoaderListener加载进来的applicationContext使用的key值不相同,因此如果只使用DispatcherServlet加载context的话,
如果程序中有地方使用WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext) 来试图获取applicationContext时,
就会抛出"No WebApplicationContext found: no ContextLoaderListener registered?"的exception。



阅读全文
0 0
原创粉丝点击