0%

spring与springmvc整合

spring与springmvc整合

在项目中使用springmvc的时候,由于spring和springmvc是同源的,有时候大家会把所有的配置都扔到springmvc的配置文件中,而不去区分spring和springmvc的配置,而我习惯于把两个配置拆分开来,spring来配置数据源、事务以及和其他框架的整合,springmvc来配置web相关的一些配置。

只使用springmvc配置

先来看一下如果只是用springmvc配置的话,如何进行配置

先配置web.xml,只需要配置DispatcherServlet即可。之后将所有的spring配置和springmvc配置都放到springmvc.xml的配置中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

区分spring和springmvc的配置

这就是本篇文章的重点了,两者整合,那就有两个配置文件了。此时就出现了spring父子容器,由ContextLoaderListener来加载spring配置文件,创建父容器;DispatcherServlet加载springmvc配置文件,创建子容器。

看一下此时的web.xml如何配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- spring配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 配置监听器,加载spring配置文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

然后分别在spring和springmvc的配置文件中配置相关的bean

在这里给大家说明一下两者配置整合时可能会遇到的一些问题

重复创建bean

当springmvc的配置文件和spring的配置文件分离的时候,由于现在使用注解的比较多,大多都是用组件扫描,

如果两个配置文件都使用<context:component-scan base-package="com.zhanghe.study.springmvc"/>来进行组件扫描的话,会导致两个配置文件都扫一遍这些组件,这些bean都会创建两次

这时候就用到了<context:exclude-filter>和<context:include-filter>来进行设置过滤了

springmvc只需要管控制器Controller就可以了,所以在springmvc的配置文件中配置

1
2
3
<context:component-scan base-package="com.zhanghe.study.springmvc" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

而spring的配置文件中只需要相应的排除掉springmvc扫描的

1
2
3
<context:component-scan base-package="com.zhanghe.study.springmvc">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

容器关系

父容器是ContextLoaderListener加载的spring配置文件,子容器是DispatcherServlet加载的spring配置文件,子容器可以访问父容器中的bean,反之则不行

获取spring容器上下文

在项目启动的时候,监听器中会在web应用环境初始化的时候将spring的上下文内容存在应用上下文中

1
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

所以在取出来时只需要获取到应用上下文

1
req.getServletContext()

然后取出来即可

1
context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)

欢迎关注我的其它发布渠道