02_spring通過xml獲取ApplicationContext

Spring中一切組件都是由javaBean構成的,所有的組件通過javaBean注入的方式形成了一個龐大的關係網。
applicationContext存放所有javaBean的實例,所以想取得spring中的bean對象,必須先取到applicationContext。


1.通過FileSystemXmlApplicationContext獲取

通過FileSystemXmlApplicationContext獲取上下文有三種方式:

1.1沒有盤符的是項目工作路徑, 即項目的根目錄;

ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
參數中的xml地址實際上是項目根目錄中xml文件的路徑。也就是說,FileSysotemXmlApplicatioContext讀取的是項目根目錄的xml文件。

所以如果配置文件可以放在項目中任意的文件夾中。通過目錄得到配置文件。例如:

BeanFactory beanFactory = new FileSystemXmlApplicationContext(
                         "WebRoot/WEB-INF/config/testApplicationContext.xml" ).getBeanFactory();

1.2有盤符表示的是文件絕對路徑。

BeanFactory beanFactory = new FileSystemXmlApplicationContext(
                       "G:\\workspace\\testApplicationContext.xml" ).getBeanFactory();
或者下面方式:

BeanFactory beanFactory = new FileSystemXmlApplicationContext(
                        "file:G:\\workspace\\testApplicationContext.xml" ).getBeanFactory();

1.3 如果要使用classpath路徑,需要前綴classpath: 

classpath指的是文件的編譯目錄。一般來說在src目錄下。在eclipse中查看classpath目錄:

將xml文件放入src目錄以後,eclipse會自動將xml文件加載到WEB-INF/classes下。

BeanFactory beanFactory = new FileSystemXmlApplicationContext(
                         "classpath:testApplicationContext.xml" ).getBeanFactory();

2.通過ClasspathXmlApplicationContext獲取

通過classpathXmlApplicationContext()獲取上下文。默認的地址找的就是項目中WEB-INF/classes目錄,所以不用加classpath。

3.通過WebApplicationContext獲取

這種獲取context方式必須在程序運行時才能獲取。需要啓動項目。

ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

web.xml中配置WebApplicationContext的兩種方法:
1.配置listener:
  <!-- Spring上下文監聽器 -->
  <listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:/application-context.xml</param-value>
  </context-param>
2.配置servlet

 <servlet>
  	<servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/application-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

配置listener和配置servlet的不同:

ContextLoaderListener中加載的context成功後,spring 將 applicationContext存放在ServletContext中key值爲"org.springframework.web.context.WebApplicationContext.ROOT"的attribute中。
獲取applicationContext:
1.WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext) 2.WebApplicationContextUtils.getWebApplicationContext(servletContext)
前者在獲取失敗時拋出異常,後者返回null。
servletContext.setAttribute(WebApplicationContext. ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE , this. context);
DispatcherServlet加載的context成功後,如果 publishContext屬性的值設置爲true的話(缺省爲true) 會將applicationContext存放在 org.springframework.web.servlet.FrameworkServlet.CONTEXT. + (servletName)的attribute中。 則對應的applicationContext的attribute key值爲org.springframework.web.servlet.FrameworkServlet.CONTEXT.mvcServlet。
在每次request請求時,DispatcherServlet會將此applicationContext存放在request中attribute 值爲 org.springframework.web.servlet.DispatcherServlet.CONTEXT中。

獲取applicationContext:
1. RequestContextUtils.getWebApplicationContext();
2. WebApplicationContextUtils.getWebApplicationContext(servletContext,attrname).
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE,getWebApplicationContext());
結論:
從上面的分析可以看出,DispatcherServlet所加載的applicationContext可以認爲是mvc私有的context,由於保 存在servletContext中的key值與通過ContextLoaderListener加載進來的applicationContext使用的key值不相同,因此如果只使用DispatcherServlet加載context的話,如果程序中有地方使用 WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext) 來試圖獲取applicationContext時,就會拋出"No WebApplicationContext found: no ContextLoaderListener registered?"的exception。
ContextLoaderListener  針對全局上下文進行加載  持久層,業務層 和試圖層都加載
DispatcherServlet 針對MVC進行上下文加載的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章