简体   繁体   English

在根上下文和servlet上下文中加载应用程序上下文有什么好处?

[英]is there any benefit of loading application context in root context and in servlet context?

I followed some spring mvc tutorial and my web.xml looks like this: 我遵循了一些春季mvc教程,而我的web.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>


        <param-value>/WEB-INF/spring/root-context.xml, /WEB-INF/spring/appServlet/servlet-context.xml</param-value>


    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>


            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>

        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<session-config>
  <session-timeout>1</session-timeout>
</session-config>

</web-app>

My question is, what is the benefit of loading servlet-context.xml in root context and in servlet context both? 我的问题是,在根上下文和servlet上下文中加载servlet-context.xml有什么好处? I am a spring framework newbie and I do not understand spring framework very well. 我是Spring框架的新手,我对Spring框架不太了解。

There is no good reason to inject the exact same configuration twice in both the servlet and the root context. 没有充分的理由在Servlet和根上下文中两次注入完全相同的配置。

The idea for having multiple contexts is the following: Most Spring MVC applications have one root context containing all service layer / DAO layer beans, and one servlet context per spring dispatcher servlet of the application, which contains (at least) the controllers of each servlet. 具有多个上下文的想法如下:大多数Spring MVC应用程序具有一个包含所有服务层/ DAO层bean的根上下文,以及该应用程序的每个Spring Dispatcher servlet一个Servlet上下文,该Servlet上下文包含(至少)每个Servlet的控制器。 。

The idea being that is that one application might have several servlet dispatchers, for example one for URL /desktop/* and the other for URL /mobile/*, each with it's own set of different controllers. 其想法是,一个应用程序可能具有多个servlet调度程序,例如一个用于URL / desktop / *,另一个用于URL / mobile / *,每个调度程序都有自己的一组不同的控制器。

The controllers of one servlet dispatcher are isolated from each other, meaning although they are also Spring beans, they cannot be injected in each other. 一个servlet调度程序的控制器是相互隔离的,这意味着尽管它们也是Spring Bean,但不能相互注入。

Service layer and DAO beans in the root context are visible in all servlet contexts, so Service layer beans can be injected in any controller, but not the other way around. 根上下文中的服务层和DAO Bean在所有Servlet上下文中都是可见的,因此可以在任何控制器中注入服务层Bean,但不能以其他方式注入。

The root context is said to be the parent of the controller servlet context/contexts. 根上下文被称为控制器Servlet上下文的父级。

It's all meant to be a mechanism of isolating groups of beans from each other to ensure no unmeant dependencies are possible. 所有这一切都是要使一组豆相互隔离的机制,以确保不会产生不协调的依赖关系。

Also there are components of the Spring framework that need a root context, for example OpenSessionInViewFilter . Spring框架中还有一些需要根上下文的组件,例如OpenSessionInViewFilter

TLDR : it's not that it's impossible to inject servlet-context.xml in both contexts, but that is not how it's meant to be used: there will two beans of each type in two separate contexts, one can have transactions applied while the other doesn't, etc., it can quickly originate errors that are hard to troubleshoot TLDR :不是不可能在两个上下文中都注入servlet-context.xml,而是这不是它的使用方式:在两个单独的上下文中将有两种类型的bean,一种可以应用事务,而另一种则不需要等),它可以快速引发难以解决的错误

In Spring, ApplicationContext can be hierarchical. 在Spring中,ApplicationContext可以是分层的。 If you have multiple webapps in a single EAR, EAR can have its own context, which is the parent of the individual webapp contexts. 如果单个EAR中有多个Web应用程序,则EAR可以具有自己的上下文,该上下文是各个Webapp上下文的父级。 Also in each webapp, you can have one root context and individual children context as well. 同样在每个Web应用程序中,您也可以有一个根上下文和单个子上下文。 You can define this hierarchy in web.xml. 您可以在web.xml中定义此层次结构。 Parent context can be specified through context parameters: locatorFactorySelector and parentContextKey. 可以通过上下文参数指定父上下文:locatorFactorySelector和parentContextKey。 Root context through context parameter contextConfigLocation(the one in context-param). 通过上下文参数contextConfigLocation(context-param中的一个)来根上下文。 Child context can be specified in the init param - param-name attribute of each of the servlet definition. 可以在每个servlet定义的init param-param-name属性中指定子上下文。

Have one jar in EAR holding all your common service and DAO layer code and define them in beanRefContext.xml(which is basically another application context xml). 在EAR中有一个jar保存所有公共服务和DAO层代码,并在beanRefContext.xml(基本上是另一个应用程序上下文xml)中定义它们。 make this jar available in classpath. 使此jar在classpath中可用。

In web.xml of each app where you want to refer parent context code: 在每个要引用父上下文代码的应用程序的web.xml中:

<!--  root application context -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:rootContextBeans.xml</param-value>
</context-param>
<!--  start shared service layer - parent application context -->
<context-param>
    <param-name>locatorFactorySelector</param-name>
    <param-value>classpath:beanRefContext.xml</param-value>
</context-param>
<context-param>
    <param-name>parentContextKey</param-name>
    <param-value>servicelayer-context</param-value>
</context-param>
<!--  end shared service layer - parent application context -->
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>     
<servlet>
    <servlet-name>dispatcherServletApp1</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
        <param-name>contextConfigLocation</param-name> 
        <param-value>classpath*:webApp1.xml</param-value> 
    </init-param> 
</servlet> where beanRefContext.xml will be like:

<beans>
  <bean id="servicelayer-context" class="org.springframework.context.support.ClassPathXmlApplicationContext">
    <constructor-arg>
      <list>
        <value>data-layer-context.xml</value>
      </list>
    </constructor-arg>
  </bean>
</beans>

If your project doesn't have multi web app type, then you don't require to specify parent application context. 如果您的项目没有多种Web应用程序类型,则无需指定父应用程序上下文。 You can move common service and DAO layer code, security to root application context(in above web.xml to rootContextBeans.xml) which can be accessed(visible) by dispatcherServlet beans (remember reverse visibility is not possible). 您可以将公共服务和DAO层代码,安全性移至根应用程序上下文(在web.xml上方移至rootContextBeans.xml),可以由dispatcherServlet Bean访问(可见)(记住,反向可见性是不可能的)。
In your web.xml you specified, servlet-context.xml in root context contextConfigLocation and in servlet contextConfigLocation. 在您的web.xml中,在根上下文contextConfigLocation和servlet contextConfigLocation中指定servlet-context.xml。 So you need to check what beans are defined in it and where it fits exactly and remove the refernce in other place. 因此,您需要检查其中定义了哪些bean,以及它完全适合的位置,并在其他位置删除引用。

All of the Spring configuration files in the root directory of 'WEB-INF/spring' are loaded in the root Spring context. “ WEB-INF / spring”的根目录中的所有Spring配置文件都被加载到Spring根目录中。

This configuration is for loading anything web related into the root context, in this case it's just the web security. 此配置用于将与Web相关的任何Web加载到根上下文中,在这种情况下,这仅仅是Web安全性。

For Reference: http://www.springbyexample.org/examples/contact-webapp-spring-config.html 供参考: http : //www.springbyexample.org/examples/contact-webapp-spring-config.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM