在 Spring 所支持的轻量级应用模型中,有一个概念叫“分层架构”。在经典的分层架构中, Web 层只是很多层中的一层...它是服务器端应用的一个入口,它将请求委派给定义在服务层的服务对象 (门面)以满足业务用例需求(这些是表现层技术触及不到的)。在 Spring 中,这些服务对象,以及其他的业务对象, 数据访问对象等等,都存在于一个独立的“businnes context”中,这个context不含有任何 Web 或者表现层的对象(表现层对象诸如 Spring MVC 控制器通常被配置于一个独立的“presentation context”中)。 这一节详细介绍在一个应用中如何配置一个 Spring 容器(WebApplicationContext
)来容纳所有的“business beans”。
现在进入细节部分...所有你需要做的就是在 Web 应用的 web.xml
文件中声明一个 ContextLoaderListener
并且在同一文件里增加一个 contextConfigLocation
<context-param/> , 这个声明决定了哪些 Spring XML 配置文件将要被加载。
以下是 <listener/> 的配置:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
注意
Listener 是在 Servlet API 2.3 版本中才加入的。如果你使用只支持 Servlet 2.2 版本的容器, 你可以使用 ContextLoaderServlet
完成相同的功能。
以下是 <context-param/> 的配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
如果你没有指定 contextConfigLocation
的context参数, ContextLoaderListener
将会寻找一个名为 /WEB-INF/applicationContext.xml
的文件以加载。 一旦context文件被加载,Spring 通过文件中 bean 的定义创建一个 WebApplicationContext
对象并且将它储存在 Web 应用的 ServletContext 中。
所有 Java Web 框架都构建在 Servlet API 之上,所以可以使用下面的代码片断访问这个 由 ContextLoaderListener
创建的ApplicationContext。
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
WebApplicationContextUtils
这个类提供了方便的功能,这样你就不必去记 ServletContext 中属性的名字。 它的 getWebApplicationContext() 方法在 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
这个键值不对应任何对象的时候将返回 null
。 不过,为了避免在应用中得到 NullPointerExceptions
,我们推荐你使用 getRequiredWebApplicationContext()
方法。 这个方法在ApplicationContext 缺失的时候会抛出一个异常。
一旦你获得了一个 WebApplicationContext
的引用, 你可以通过 bean 的名字或类型来获得它们。大多数开发人员通过名字获得 bean, 然后将它们转换成相应的接口类型。
幸运的是,这一节中的大多数框架都有更简单的方法来查询 bean。我们不仅仅可以更简单地从 Spring 容器中 得到 bean,我们还可以在控制器中使用 Spring 依赖注入的特性。下面的几个小节是每种框架集成策略的详细描述。