web项目如何获取容器

来源:互联网 发布:安卓数据恢复软件 编辑:程序博客网 时间:2024/06/10 10:51
spring通过在web.xml 中配置ContextLoaderListener 来加载context配置文件,在DispatcherServlet中也可以来加载spring context配置文件,那么这两个有什么区别呢。 

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中。 

例如 web.xml中配置如下 
Xml代码  
    <servlet>  
        <servlet-name>mvcServlet</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>classpath*:/spring/config/applicationContextMVC.xml</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>  
    </servlet> 

则对应的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。 

那我们怎么取了? 
ApplicationContext ac = (WebApplicationContext) this.getServeltContext().getAttribute("org.springframework.web.servelt.FrameworkServlet.CONTEXT.这里填写web.xml配置的servlet的名称"); 

http://pbcljf.blog.163.com/blog/static/340340192010513537424/ 
方法一:在初始化时保存ApplicationContext对象 
代码: 
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml"); 
ac.getBean("beanId"); 
说明:这种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Spring的情况。 

方法二:通过Spring提供的工具类获取ApplicationContext对象 
代码: 
import org.springframework.web.context.support.WebApplicationContextUtils; 
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc); 
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc); 
ac1.getBean("beanId"); 
ac2.getBean("beanId"); 
说明: 
这种方式适合于采用Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象,然后在通过它获取需要的类实例。 

上面两个工具方式的区别是,前者在获取失败时抛出异常,后者返回null。 

其中 servletContext sc 可以具体 换成 servlet.getServletContext()或者 this.getServletContext() 或者 request.getSession().getServletContext(); 另外,由于spring是注入的对象放在ServletContext中的,所以可以直接在ServletContext取出 WebApplicationContext 对象: WebApplicationContext webApplicationContext = (WebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); 

方法三:继承自抽象类ApplicationObjectSupport 
说明:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。 
Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。 

方法四:继承自抽象类WebApplicationObjectSupport 
说明:类似上面方法,调用getWebApplicationContext()获取WebApplicationContext 

方法五:实现接口ApplicationContextAware 
说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。 
Spring初始化时,会通过该方法将ApplicationContext对象注入。 


在web应用中一般用ContextLoaderListener加载webapplication,如果需要在action之外或者control类之外获取webapplication思路之一是,单独写个类放在static变量中, 
类似于: 
public class AppContext { 

  private static AppContext instance; 

  private AbstractApplicationContext appContext; 

  public synchronized static AppContext getInstance() { 
    if (instance == null) { 
      instance = new AppContext(); 
    } 
    return instance; 
  } 

  private AppContext() { 
    this.appContext = new ClassPathXmlApplicationContext( 
        "/applicationContext.xml"); 
  } 

  public AbstractApplicationContext getAppContext() { 
    return appContext; 
  } 


不过这样,还是加载了2次applicationcontext,servlet一次,路径加载一次;觉得不如直接用路径加载,舍掉servlet加载 
在网上也找了些其他说法:实现ApplicationContextAware,,, 接口,或者servletcontextAware接口,还要写配置文件。有的竟然要把配置文件里的listener,换成自己的类,这样纯粹多此一举。不过有的应用不是替换,是在补一个listener, 
我在一版的jpetstore(具体那一版不知道)里发现了这个: 
[web.xml]里 
      
    <listener> 
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
    
    <listener> 
        <listener-class>com.ibatis.jpetstore.util.SpringInit</listener-class> 
    </listener> 
其中SpringInit实现接口ServletContextListener : 

package com.ibatis.jpetstore.util; 

import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 
import org.springframework.context.ApplicationContext; 
import org.springframework.web.context.WebApplicationContext; 
import org.springframework.web.context.support.WebApplicationContextUtils; 


public class SpringInit implements ServletContextListener { 
    

    private static WebApplicationContext springContext; 
    
    public SpringInit() { 
        super(); 
    } 
    
    public void contextInitialized(ServletContextEvent event) { 
        springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext()); 
    } 
    

    public void contextDestroyed(ServletContextEvent event) { 
    } 
    
    public static ApplicationContext getApplicationContext() { 
        return springContext; 
    } 

    


在其中的一个bean的构造里SpringInit获取applicationcontext,代码: 
  public OrderBean() { 
    this( 
            (AccountService) SpringInit.getApplicationContext().getBean("accountService"), 
            (OrderService) SpringInit.getApplicationContext().getBean("orderService") ); 
  } 

恩,这种在action,servlet之外的bean里获取applicationcontext的方法值得参考,应该有用 
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 辞职了户口迁回农原籍不接收怎么办 当正职直接指挥下级副职领导怎么办 单位申报个税身份证号码填错怎么办 申报个税身份证号码填错了怎么办 办了人事代理联系函商调函怎么办 劳务公司与分包工头算账成怎么办 客户退保业务员己得保险佣金怎么办 投了简历公司打来电话没接到怎么办 跟老板要工资她说过几天怎么办 公路车弯把手小抓不到刹车怎么办 新手骑电动车上路车子一直晃怎么办 不知情收赃东西已经卖了怎么办 档案和派遣证不在同一个地方怎么办 档案缺招工表和派遣证怎么办退休 开发商对接的银行利息比较高怎么办 工作未满一年离职转正定级怎么办 被网络骗贷翻到几十万怎么办 面试通过后迟迟不通知入职怎么办 厂里捡到饭卡花了里面的钱怎么办 上班用自己手机打卡没电怎么办 逸尚考勤机显示超出考勤记录怎么办 下雨穿套裙工装上班好冷怎么办 蚂蚁借呗放款中不到账怎么办 护士电子化注册没有激活码怎么办? 地铁站务员入职体检身高差点怎么办 车子钥匙锁在车里了怎么办 打错账户了怎么办5天了 下岗失业人员在就业后档案怎么办 皮秒祛斑后没有敷面膜怎么办 硕士毕业工资好低不想工作怎么办 车卖了etc忘拿了怎么办 成熟卵泡打破卵针也不破怎么办? 深圳孩子户口挂别人名下上学怎么办 襄阳东风合运花园房贷怎么办下来 猫在外面躲起来找不到了怎么办 本科三批取消以后三本学校怎么办 机票名字多了个字母安检怎么办 出隧道口限速40超速了怎么办 社保交了五年后断交以后该怎么办 躺椅折叠椅坐的地方坏了怎么办 苹果手机锁频密码忘了怎么办