在Spring框架中,applicationContext.xml和Spring -servlet.xml是相关的吗? 在applicationContext.xml中声明的属性文件对DispatcherServlet可用吗? 另外,为什么我需要一个*-servlet.xml呢?为什么单独的applicationContext.xml不够?


当前回答

在spring-servlet.xml中,我们包含了Controller包的组件扫描。 在下面的例子中,我们包含了控制器包的过滤器注释。

<!-- 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>

其他回答

在spring-servlet.xml中,我们包含了Controller包的组件扫描。 在下面的例子中,我们包含了控制器包的过滤器注释。

<!-- 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>

Spring允许您在父子层次结构中定义多个上下文。

xml定义了“根webapp上下文”的bean,即与webapp相关的上下文。

spring-servlet.xml(或其他任何名称)为一个servlet的应用程序上下文定义bean。在一个webapp中可以有很多这样的文件,每个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上下文是不必要的。它通常用于包含在web应用程序中所有servlet之间共享的bean。如果您只有一个servlet,那么没有什么意义,除非您对它有特定的用途。

场景1

在客户端应用程序(应用程序不是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是不相关的。

场景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从所有四个配置文件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

在web应用程序与spring MVC。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。

现在应该很清楚为什么它们在哪种情况下很重要了。

在Servlet技术中,如果你想将任何输入传递给特定的Servlet,那么你需要像下面的代码一样传入初始化参数。

 <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>

如果您想在put中传递一些对所有servlet都通用的参数,那么此时您需要配置上下文参数。例子

 <context-param>
    <param-name>email</param-name>
    <param-value>admin@example.com</param-value>
</context-param>

所以就像这样,当我们使用Spring MVC时,我们需要通过init参数向Spring提供的DispatcherServlet提供一些信息。 因此,配置是休耕的,这里我们将spring-servlet.xml作为初始参数提供给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>

同样,我们需要一些context参数。适用于整个应用。 我们可以提供根上下文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>

简单地说,

xml定义了在所有servlet之间共享的bean。如果您的应用程序有多个servlet,那么在applicationContext.xml中定义公共资源会更有意义。

xml定义了仅与该servlet相关的bean。这里是dispatcher servlet。所以,你的Spring MVC控制器必须在这个文件中定义。

如果在web应用程序中只运行一个servlet,那么在spring-servlet.xml中定义所有bean并没有什么错。