前幾天不是一個(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
阿成 閱讀(344)
評(píng)論(0) 編輯 收藏 所屬分類:
Struts