Spring和SpringMVC的容器具有父子关系,Spring容器为父容器,SpringMVC为子容器,子容器可以引用父容器中的Bean,而父容器不可以引用子容器中的Bean。
1. Spring父容器配置
<context:component-scan base-package="com.coamctech.eastlending"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
注:在父容器中会排除对controller注解的扫描,会将此扫描放在Spring MVC子容器中进行,主要是为了能够分清职责,重复扫描也可能引起事务失效。
2. Spring MVC子容器配置
<context:component-scan base-package="com.coamctech.eastlending" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
3. Spring父容器(ioc)初始化过程
(1)、web应用程序启动时,tomcat会读取web.xml文件中的context-parm(含有配置文件的路径)和listener节点,接着会为应用程序创建一个ServletContext,为全局共享,Spring ioc容器就是存储在这里
(2)、tomcat将context-param节点转换为键值对,写入到ServletContext中
(3)、创建listener节点中的ContextLoaderListener实例,调用该实例,初始化webapplicationContext,这是一个接口,其实现类为XmlWebApplicationContext(即spring的IOC容器),其通过ServletContext.getinitialParameter("contextConfigLoaction")从ServletContext中获取context-param中的值(即spring ioc容器配置文件的路径)。然后根据配置文件的路径加载配置文件信息(其中含有Bean的配置信息)到WebApplicationContext(即spring ioc容器)中,将WebApplicationContext以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取。至此,spring ioc容器初始化完毕
(4)、容器初始化web.xml中配置的servlet,为其初始化自己的上下文信息servletContext,并加载其设置的配置信息到该上下文中。将WebApplicationContext(即spring ioc容器)设置为它的父容器。其中便有SpringMVC(假设配置了SpringMVC),这就是为什么spring ioc是springmvc ioc的父容器的原因
4. Spring MVC子容器(ioc)初始化过程
SpringMVC通过web.xml文件中servlet标签下的DispatcherServlet类完成自身的初始化
DispatcherServlet类的继承体系如下:
请注意每个长方形中第三行的方法,其为完成SpringMVC ioc容器初始化的关键。
我们知道,每个servlet在初始化时,会先调用servlte的构造函数(为默认构造函数),接着调用init函数,而DispatcherServlet的init方法在其父类HttpServlet中。
initMultipartResolver(context);//文件上传解析
initLocaleResolver(context);//本地解析
initThemeResolver(context);//主题解析
initHandlerMappings(context);//url请求映射
initHandlerAdapters(context);//初始化真正调用controloler方法的类
initHandlerExceptionResolvers(context);//异常解析
initRequestToViewNameTranslator(context);
initViewResolvers(context);//视图解析