spring有三种启动方式,使用ContextLoaderServlet,ContextLoader

spring有三种启动方式,使用ContextLoaderServlet,ContextLoaderListener和ContextLoaderPlugIn.
看一下ContextLoaderListener的源码,这是一个ServletContextListener
/**
   * Initialize the root web application context.
   */
public void contextInitialized(ServletContextEvent event) {
   this.contextLoader = createContextLoader();
   this.contextLoader.initWebApplicationContext(event.getServletContext());
}

   /**
   * Create the ContextLoader to use. Can be overridden in subclasses.
   * @return the new ContextLoader
   */
protected ContextLoader createContextLoader() {
   return new ContextLoader();
}

contextLoader的源码
public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
    throws BeansException {

   long startTime = System.currentTimeMillis();
   if (logger.isInfoEnabled()) {
    logger.info("Root WebApplicationContext: initialization started");
   }
   servletContext.log("Loading Spring root WebApplicationContext");

   try {
    // Determine parent for root web application context, if any.
    ApplicationContext parent = loadParentContext(servletContext);

    WebApplicationContext wac = createWebApplicationContext(servletContext, parent);
    servletContext.setAttribute(
      WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);

    if (logger.isInfoEnabled()) {
     logger.info("Using context class [" + wac.getClass().getName() +
       "] for root WebApplicationContext");
    }
    if (logger.isDebugEnabled()) {
     logger.debug("Published root WebApplicationContext [" + wac +
       "] as ServletContext attribute with name [" +
       WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
    }

    if (logger.isInfoEnabled()) {
     long elapsedTime = System.currentTimeMillis() - startTime;
     logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
    }

    return wac;
   }
   catch (RuntimeException ex) {
    logger.error("Context initialization failed", ex);
    servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
    throw ex;
   }
   catch (Error err) {
    logger.error("Context initialization failed", err);
    servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
    throw err;
   }
}
注意WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,这里面放了WebApplicationContext,需要使用时从ServletContext取出
可以使用WebApplicationContextUtils得到WebApplicationContext
public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
   Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
   if (attr == null) {
    return null;
   }
   if (attr instanceof RuntimeException) {
    throw (RuntimeException) attr;
   }
   if (attr instanceof Error) {
    throw (Error) attr;
   }
   if (!(attr instanceof WebApplicationContext)) {
    throw new IllegalStateException("Root context attribute is not of type WebApplicationContext: " + attr);
   }
   return (WebApplicationContext) attr;
}
关键的问题在于struts如何启动的spring的,ContextLoaderPlugIn的源码

// Publish the context as a servlet context attribute.
   String attrName = getServletContextAttributeName();
   getServletContext().setAttribute(attrName, wac);

public String getServletContextAttributeName() {
   return SERVLET_CONTEXT_PREFIX + getModulePrefix();
}
不同加载的Key竟然不同,原因就是WebApplicationContext放在那里的问题,可spring调用的时候会根据WebApplicationContext里面定义的那个名字去找的,问题出在这里


在struts-config.xml中配置
     <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
       <set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
     </plug-in>

     <controller>
         <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor" />
     </controller>


原理是这样的,Struts虽然只能有一个ActionServlet实例,但是对于不同的子应用分别能有自己的RequestProcessor实例每个RequestProcessor实例分别对应不同的struts配置文件。
    子应用的ProcessorClass类必须重写一般就是继承RequestProcessor类,然后再其配置文件的controller元素中的<processorClass>属性中作出修改。那么当
   getRequestProcessor(getModuleConfig(request)).process(request,response); 就能根据request选择相应的moduleconfig,再根据其<processorClass>属性选择相应的 RequestProcessor子类来处理相应的请求了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值