本章主要讲述1、分析Spring的IoC容器是怎样在Web应用环境中发挥作用的 2、分析Spring MVC框架的实现原理
4.2 Web环境中的Spring MVC
如果要在Web环境中使用IoC容器,需要Spring为IoC设计一个启动过程。
http://blog.csdn.net/zuoluoboy/article/details/4213053 (web.xml的作用到底是什么,如何配置web.xml)
主要的一些元素:
23、配置Spring IoC容器读取Bean定义的XML文件的路径
<!-- 指定spring配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
<!--加载多个spring配置文件 -->
/WEB-INF/applicationContext.xml, /WEB-INF/action-servlet.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
DispatcherServlet与ContextLoaderListener,这些接口与Web容器耦合是通过ServletContext来实现的。在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,在该环境中,Spring MVC建立起一个IoC容器的体系。
4.3.1 IoC容器启动的基本过程
上下文体系的建立由ContextLoader完成,一个是在Web容器中建立起双亲IoC容器,另一个是生成相应的WebApplicationContext并将其初始化。
4.3.2 Web容器中的上下文设计
为了方便在Web环境下使用IoC容器,Spring为Web应用提供了上下文的扩展接口WebApplicationContext来满足启动过程的需要。
可以看到,Web应用上下文的实现是基于基本Ioc容器ApplicatoionContext相关接口,并在此基础上加入了适用于Web环境的相关功能扩展。
1)
WebApplicationContext接口实现
public interface WebApplicationContext extends ApplicationContext {
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
String SCOPE_REQUEST = "request";
String SCOPE_SESSION = "session";
...
...
ServletContext getServletContext();
}
在该接口中,定义了几个常量,比如ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,这个常量用于索引在ServletContext中保存的根上下文。还有就是ServletContext getServletContext()方法,通过这个方法可以得到当前web容器的Servlet上下文环境。
2)Spring MVC使用的WebApplicationContext实现
Spring MVC使用一个默认的WebApplicationContext来作为IoC容器,这个IoC容器就是XmlWebApplicationContext。
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
//默认的根环境配置文件路径,/WEB-INF/applicationContext.xml
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
//默认的配置文件目录前缀和文件后缀
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
//loadBeanDefinitions函数,在Ioc容器启动时,通过该函数加载、注册BeanDefinition
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//用XmlBeanDefinitionReader 类来对BeanDefinition信息进行解析
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(getEnvironment());
//设置ResourceLoader资源导入器,因ApplicationContext是DefaultResource子类,因此这里传入this,使用该DefaultResourceLoader来定位BeanDefinition资源文件
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
//通过定义好的XmlBeanDefinitionReader 来载入BeanDefinition。
loadBeanDefinitions(beanDefinitionReader);
}
protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
}
//对多个BeanDefinition定义文件,通过XmlBeanDefinitionReader 逐个载入
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
reader.loadBeanDefinitions(configLocation);
}
}
}
//获取默认资源位置,默认的位置是/WEB-INF/applicationContext.xml
@Override
protected String[] getDefaultConfigLocations() {
if (getNamespace() != null) {
return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
}
else {
return new String[] {DEFAULT_CONFIG_LOCATION};
}
}
}
3)ContextLoader的设计与实现