posts - 120,  comments - 19,  trackbacks - 0

          前幾天不是一個(gè)同事使用OpenSessionInView pattern時(shí),遇到Hibernate 3的mappinglazy="true"的問題,也不會(huì)想到它
          struts啟動(dòng)spring的WebApplicationContext
          spring有三種啟動(dòng)方式,使用ContextLoaderServlet,ContextLoaderListener和ContextLoaderPlugIn.
          看一下ContextLoaderListener的源碼,這是一個(gè)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,需要使用時(shí)從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;
          ?}
          ?關(guān)鍵的問題在于struts如何啟動(dòng)的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調(diào)用的時(shí)候會(huì)根據(jù)WebApplicationContext里面定義的那個(gè)名字去找的,問題出在這里


          ?在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雖然只能有一個(gè)ActionServlet實(shí)例,但是對(duì)于不同的子應(yīng)用分別能有自己的RequestProcessor實(shí)例每個(gè)RequestProcessor實(shí)例分別對(duì)應(yīng)不同的struts配置文件。
          ?? 子應(yīng)用的ProcessorClass類必須重寫一般就是繼承RequestProcessor類,然后再其配置文件的controller元素中的<processorClass>屬性中作出修改。那么當(dāng)
          ? getRequestProcessor(getModuleConfig(request)).process(request,response);就能根據(jù)request選擇相應(yīng)的moduleconfig,再根據(jù)其<processorClass>屬性選擇相應(yīng)的RequestProcessor子類來處理相應(yīng)的請(qǐng)求了。



          posted on 2006-08-22 16:14 阿成 閱讀(350) 評(píng)論(0)  編輯  收藏 所屬分類: Struts
          主站蜘蛛池模板: 金寨县| 嘉荫县| 海伦市| 河南省| 达拉特旗| 西丰县| 乾安县| 黔西县| 百色市| 江阴市| 鹤峰县| 镇安县| 改则县| 湟中县| 临颍县| 芒康县| 西畴县| 龙州县| 望江县| 唐海县| 江津市| 宿州市| 渭源县| 华蓥市| 方正县| 延长县| 商都县| 元谋县| 突泉县| 安顺市| 隆林| 浑源县| 炎陵县| 乐东| 天镇县| 金坛市| 彰武县| 福州市| 杭州市| 漾濞| 天水市|