Spring框架中applicationContext.xml和spring - servlet.xml的区别
技术背景
在Spring框架里,applicationContext.xml
和spring - servlet.xml
是两个重要的配置文件。Spring允许在父子层次结构中定义多个上下文,这两个文件在不同场景下发挥着不同的作用,理解它们的区别对于Spring应用的开发和配置至关重要。
实现步骤
父子上下文关系
applicationContext.xml
:定义“根Web应用上下文”的Bean,即与Web应用关联的上下文。此上下文中的Bean通常是在整个Web应用的所有Servlet之间共享的。例如,在一个包含多个Servlet的Web应用中,用于数据库连接池、事务管理器等的Bean可以定义在applicationContext.xml
中。spring - servlet.xml
:定义单个Servlet的应用上下文的Bean。一个Web应用中可以有多个这样的文件,每个Spring Servlet对应一个(例如,spring1 - servlet.xml
对应Servlet spring1
,spring2 - servlet.xml
对应Servlet spring2
)。所有Spring MVC控制器必须放在spring - servlet.xml
上下文中。
配置示例
以下是web.xml
中常见的配置示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param>
<servlet> <servlet-name>springweb</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springweb-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springweb</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
|
组件扫描配置
- 在
spring - servlet.xml
中,通常对Controller包进行组件扫描:
1 2 3
| <context:component-scan base-package="org.test.web" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
|
- 在
applicationContext.xml
中,对除Controller之外的包进行组件扫描:
1 2 3
| <context:component-scan base-package="org.test"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
|
核心代码
applicationContext.xml
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="test1.xml" /> <import resource="test2.xml" /> <import resource="test3.xml" /> <import resource="test4.xml" />
<context:component-scan base-package="org.test"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> </beans>
|
spring - servlet.xml
示例
1 2 3 4 5 6 7 8 9 10 11 12 13
| <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.test.web" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> </beans>
|
最佳实践
- 单Servlet应用:如果Web应用中只有一个Servlet,在很多情况下
applicationContext.xml
不是必需的。可以将所有Bean定义在spring - servlet.xml
中。 - 多Servlet应用:当Web应用包含多个Servlet时,将共享的Bean定义在
applicationContext.xml
中,每个Servlet特定的Bean定义在对应的*-servlet.xml
文件中,这样可以提高代码的可维护性和可扩展性。
常见问题
Bean重复创建问题
如果在contextConfigLocation
中同时包含dispatcher - servlet.xml
和DispatcherServlet
的配置,可能会导致Bean被初始化两次。解决方法是确保contextConfigLocation
和DispatcherServlet
的配置文件不重复。
找不到Controller问题
如果Controller没有被正确扫描到,可能是spring - servlet.xml
中的组件扫描配置有误。需要确保base - package
配置正确,并且使用了正确的include - filter
。