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;
- }
- ……
- }
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>
<bean id="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”);
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”);
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>
<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>
<bean id="myBean"> <property name="config"> <value>classpath:myConfig.xml</value> </property> </bean>
这样,无论ApplicationContext的实现是什么,它总会到classpath中去查找myConfig.xml资源