本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告

戒除浮躁,读好书,交益友


我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:邢红瑞的blog
日志总数:523
评论数量:1142
留言数量:0
访问次数:9691658
建立时间:2004年12月20日




[j2ee]Struts加载spring的问题
原创空间,  软件技术

邢红瑞 发表于 2005/8/5 8:41:29

前几天不是一个同事使用OpenSessionInView pattern时,遇到Hibernate 3的mappinglazy="true"的问题,也不会想到它struts启动spring的WebApplicationContextspring有三种启动方式,使用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子类来处理相应的请求了。      


阅读全文(4116) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.055 second(s), page refreshed 144751195 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号