Spring框架中的applicationContext.xml和spring-servlet.xml之间的区别
- Spring框架中的
applicationContext.xml
和spring-servlet.xml
相关? - 在
applicationContext.xml
声明的属性文件是否可用于DispatcherServlet
? - 在相关说明中,为什么我需要一个
*-servlet.xml
呢? 为什么applicationContext.xml
本身不够?
Spring允许您在父子层次结构中定义多个上下文。
applicationContext.xml
为“根web应用程序上下文”定义了bean,即与web应用程序相关的上下文。
spring-servlet.xml
(或其他你称之为的)定义了一个servlet的应用上下文的bean。 在webapp中可以有许多这样的,每个Spring servlet spring1-servlet.xml
一个(例如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,那么没有多less意义,除非你有特定的用途。
情况1
在客户端应用程序(应用程序不是Web应用程序,例如可能是挥杆应用程序
private static ApplicationContext context = new ClassPathXmlApplicationContext("test-client.xml"); context.getBean(name);
不需要web.xml 。 ApplicationContext作为获取bean服务的容器。 无需Web服务器容器。 在test-client.xml中可以有不带远程处理的Simple bean,带有远程处理的Bean。
结论 :在场景1中,applicationContext和DispatcherServlet
没有关系。
情景2
在一个服务器应用程序(应用程序部署在服务器,如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从所有四个configuration文件test1.xml , test2.xml , test3.xml , test4.xml中实例化。
结论 :在场景2中applicationContext和DispatcherServlet
没有关系。
情景3
在一个带有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
没有关系。
场景4
在与Spring MVC的Web应用程序。 用于servlet和applicationContext.xml的 springweb-servlet.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。
现在它明确了为什么它们在哪种情况下很重要。
还有一点我想补充一点。 在spring-servlet.xml
我们包含了Controller包的组件扫描。 在下面的例子中,我们包含了控制器包的filter注释。
<!-- 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
我们为除控制器之外的其余包添加filter。
<context:component-scan base-package="org.test"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
简而言之,
applicationContext.xml
定义了所有servlet之间共享的bean。 如果您的应用程序有多个servlet,那么在applicationContext.xml
定义公共资源会更有意义。
spring-servlet.xml
定义了仅与该servlet相关的bean。 这里是调度程序servlet。 所以,你的Spring MVC控制器必须在这个文件中定义。
如果在Web应用程序中只运行一个servlet,那么定义spring-servlet.xml
中的所有bean没有任何问题。
应用程序上下文提供了解决文本消息的手段,包括对这些消息的支持。 应用程序上下文提供了加载文件资源(如图像)的通用方法。 应用程序上下文可以将事件发布到注册为侦听器的bean。 容器中的某些操作或容器中的bean,必须以编程方式与bean工厂一起处理,可以在应用程序上下文中声明性地处理。 ResourceLoader支持:Spring的Resource为我们提供了一个灵活的通用抽象来处理底层资源。 应用程序上下文本身是一个ResourceLoader,因此可以让应用程序访问特定于部署的Resource实例。 MessageSource支持:应用程序上下文实现MessageSource,一个用于获取本地化消息的接口,实际的实现是可插入的
在Servlet技术中,如果你想把任何input传递给一个特定的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都通用的东西,那么你需要configuration上下文参数。 例
<context-param> <param-name>email</param-name> <param-value>admin@example.com</param-value> </context-param>
当我们正在使用Spring MVC时,就像这样,我们需要提供一些信息给Spring提供的预定义servlet,通过init参数来调用DispatcherServlet。 所以configuration就像休闲一样,在这里我们将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的根环境configuration是这样的:
<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>