【发布时间】:2011-04-08 19:14:27
【问题描述】:
-
applicationContext.xml和spring-servlet.xml在 Spring Framework 中是否相关?
-
applicationContext.xml中声明的属性文件是否可用于DispatcherServlet?
- 在相关说明中,我为什么需要
*-servlet.xml?为什么单独applicationContext.xml不够?
【问题讨论】:
applicationContext.xml 和 spring-servlet.xml 在 Spring Framework 中是否相关?applicationContext.xml 中声明的属性文件是否可用于DispatcherServlet?*-servlet.xml?为什么单独applicationContext.xml 不够? 【问题讨论】:
Spring 允许您在父子层次结构中定义多个上下文。
applicationContext.xml 定义了“根 webapp 上下文”的 bean,即与 webapp 关联的上下文。
spring-servlet.xml(或任何其他名称)为一个 servlet 的应用程序上下文定义了 bean。在一个 web 应用程序中可以有许多这些,每个 Spring servlet 一个(例如,spring1-servlet.xml 用于 servlet spring1,spring2-servlet.xml 用于 servlet spring2)。
spring-servlet.xml 中的 Bean 可以引用 applicationContext.xml 中的 bean,反之则不行。
所有 Spring MVC 控制器都必须进入 spring-servlet.xml 上下文。
在大多数简单的情况下,applicationContext.xml 上下文是不必要的。它通常用于包含在 webapp 中的所有 servlet 之间共享的 bean。如果您只有一个 servlet,那么没有什么意义,除非您对它有特定用途。
【讨论】:
我还要补充一点。在spring-servlet.xml 中,我们包括对控制器包的组件扫描。
在下面的示例中,我们包含控制器包的过滤器注释。
<!-- Scans for annotated @Controllers in the classpath -->
<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 中,我们为除控制器之外的剩余包添加过滤器。
<context:component-scan base-package="org.test">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
【讨论】:
@Controller bean(Spring MVC 需要)。
在客户端应用程序中(应用程序不是 Web 应用程序,例如可能是 Swing 应用程序)
private static ApplicationContext context = new ClassPathXmlApplicationContext("test-client.xml");
context.getBean(name);
不需要 web.xml。 ApplicationContext 作为获取 bean 服务的容器。不需要 Web 服务器容器。 在 test-client.xml 中可以有没有远程处理的简单 bean,有远程处理的 bean。
结论:在场景 1 中 applicationContext 和 DispatcherServlet 不相关。
在服务器应用程序中(部署在服务器中的应用程序,例如 Tomcat)。通过客户端程序(例如 Swing 应用程序)远程访问服务
在web.xml中定义监听器
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
在服务器启动时ContextLoaderListener 实例化 applicationContext.xml 中定义的 bean。
假设您在 applicationContext.xml 中定义了以下内容:
<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />
bean 是从所有四个配置文件 test1.xml、test2.xml、test3.xml、test4 中实例化的。 xml.
结论:在场景2中applicationContext和DispatcherServlet不相关。
在带有 Spring MVC 的 Web 应用程序中。
在 web.xml 中定义:
<servlet>
<servlet-name>springweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springweb</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
当 Tomcat 启动时,springweb-servlet.xml 中定义的 bean 被实例化。
DispatcherServlet 扩展了 FrameworkServlet。在 FrameworkServlet bean 实例化发生在 springweb 中。在我们的例子中 springweb 是 FrameworkServlet。
结论:在场景3中applicationContext和DispatcherServlet不相关。
在带有 Spring MVC 的 Web 应用程序中。 springweb-servlet.xml 用于 servlet 和 applicationContext.xml 用于访问服务器程序中的业务服务或访问另一个服务器程序中的 DB 服务。
在 web.xml 中定义了以下内容:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springweb</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
在服务器启动时,ContextLoaderListener 实例化 applicationContext.xml 中定义的 bean;假设您已在此声明:
<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />
bean 都是从所有四个 test1.xml、test2.xml、test3.xml、test4.xml 实例化的。 applicationContext.xml中定义的bean实例化完成后,springweb-servlet.xml中定义的bean被实例化。
所以实例化顺序是:根(应用程序上下文),然后是 FrameworkServlet。
现在应该清楚为什么它们在哪种情况下很重要。
【讨论】:
DispatcherServlet 如果 url 不以 .action 结尾,则不会调用?
应用程序上下文提供了一种解析文本消息的方法,包括对这些消息的 i18n 的支持。 应用程序上下文提供了一种加载文件资源(例如图像)的通用方法。 应用程序上下文可以将事件发布到注册为侦听器的 bean。 容器或容器中的 bean 上的某些操作,必须通过 bean 工厂以编程方式处理,可以在应用程序上下文中以声明方式处理。 ResourceLoader 支持:Spring 的 Resource 接口使用灵活的通用抽象来处理低级资源。应用程序上下文本身是一个 ResourceLoader,因此为应用程序提供了对特定于部署的资源实例的访问权限。 MessageSource 支持:应用上下文实现 MessageSource,一个用于获取本地化消息的接口,实际实现是可插拔的
【讨论】:
简单来说,
applicationContext.xml 定义在所有 servlet 之间共享的 bean。如果您的应用程序有多个 servlet,那么在 applicationContext.xml 中定义公共资源会更有意义。
spring-servlet.xml 定义仅与该 servlet 相关的 bean。这里是调度程序 servlet。所以,你的 Spring MVC 控制器必须在这个文件中定义。
如果您在 Web 应用程序中只运行一个 servlet,那么在 spring-servlet.xml 中定义所有 bean 并没有错。
【讨论】:
在 Servlet 技术中,如果您想将任何输入传递给特定的 servlet,那么您需要像下面的代码一样传入 init 参数。
<servlet>
<servlet-name>DBController</servlet-name>
<servlet-class>com.test.controller.DBController</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>John</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DBController</servlet-name>
<url-pattern>/DBController</url-pattern>
</servlet-mapping>
如果你想传递一些对所有 servlet 通用的输入,那么你需要配置上下文参数。示例
<context-param>
<param-name>email</param-name>
<param-value>admin@example.com</param-value>
</context-param>
当我们使用 Spring MVC 时,就像这样,我们需要通过 init 参数向 Spring 提供的预定义 servlet 提供一些信息,即 DispatcherServlet。 所以配置是休闲的,这里我们将 spring-servlet.xml 作为 init 参数提供给 DispatcherServlet。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>Spring MVC App</display-name>
<servlet>
<servlet-name>SpringController</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringController</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
我们再次需要一些上下文参数。这适用于整个应用程序。 所以我们可以提供根上下文,即 applicationcontext.xml 配置是这样的:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationcontext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>SpringController</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringController</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
【讨论】: