Spring將各種形式的資源封裝成一個統一的Resource接口。通過這個Resource接口,你可以取得URL、InputStream和File對象。當然,Resource對象所代表的資源可能不存在,此時InputStream就取不到。如果Resource不是代表文件系統中的一個文件,那麼File對象也是取不到的。
Spring通過“注入”的方式來設置資源。假如你有一個Java類:
public class MyBean {
private Resource config;
public void setConfig(Resource config) {
this.config = config;
}
……
}
Spring配置文件beans.xml
<bean id="myBean" class="MyBean">
<property name="config">
<value>myConfig.xml</value>
</property>
</bean>
這樣,Spring就會把適當的myConfig.xml所對應的資源注入到myBean對象中。那麼Spring是如何找到配置文件中“myConfig.xml”文件的呢?在不同的環境中有不同的結果。
1)如果我以下面的方式啓動Spring容器:ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
那麼系統將會在classpath中查找myConfig.xml文件,並注入到myBean對象中。相當於:myBean.setConfig(getClassLoader().getResource("myConfig.xml")。
2)如果我以下面的方式啓動Spring:
ApplicationContext context = new FileSystemXmlApplicationContext("C:/path/to/beans.xml");
那麼系統將會在文件系統中查找myConfig.xml文件。相當於:myBean.setConfig(new File("myConfig.xml"))。
3) 如果我在Web應用中,用ContextLoader來啓動Spring(/WEB-INF/web.xml片段如下所示):
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
ContextLoaderListener會創建一個XmlWebApplicationContext作爲Spring容器。因此,系統將會在Web應用的根目錄中查找myConfig.xml。相當於:myBean.setConfig(servletContext.getResource("myConfig.xml"))。Spring是如何做到這一點的呢?原來在Spring中,ApplicationContext對象不僅繼承了BeanFactory接口(代表bean的容器),更重要的是,它搭起了beans和運行環境之間的橋樑 —— 所有的ApplicationContext都實現了ResourceLoader接口。因此它們可以根據不同的環境,用適當的方式來裝載資源。
另外,Spring還有一種特別的資源表示法:
<bean id="myBean" class="MyBean">
<property name="config">
<value>classpath:myConfig.xml</value>
</property>
</bean>
這樣,無論ApplicationContext的實現是什麼,它總會到classpath中去查找myConfig.xml資源