spring有三种启动方式

spring有三种启动方式,使用ContextLoaderServlet,ContextLoaderListener和ContextLoaderPlugIn.

 

看一下ContextLoaderListener的源码,这是一个ServletContextListener

[

 (
     
public interface ServletContextListener extends EventListener {

        public void contextInitialized ( ServletContextEvent sce );        
        public void contextDestroyed ( ServletContextEvent sce );
}
 
 )

   ServletContextListener接口有两方需要实现的方法:contextInitialized()和contextDestroyed();

   Listener,译为监听者.顾名思义,它会监听Servlet容器,当应用开始的时候它会调用contextInitialized()方法;
   当应用关闭的时候,它同样会调用contextDestroyed()方法.

   我们可以利用这个特性初始化一些信息,当然我们也可以利用Servlet类init()方法,并在配置文件中让它启动应用的时候
   就执行,并且在关闭的时候执行destroy()方法.但是继承此接口应该更符合容器的应用. 

]


 

/**
  * 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子类来处理相应的请求了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值