由于加倍的上下文(servlet + ContextLoaderListener),所有Spring Framework bean都会重复 [英] All Spring Framework beans get duplicated, becase of doubled context (servlet+ContextLoaderListener)

查看:141
本文介绍了由于加倍的上下文(servlet + ContextLoaderListener),所有Spring Framework bean都会重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  • 如果我通过调度程序servlet创建弹簧上下文 ,我在 DelegatingFilterProxy 过滤器中出错:

  • If I create spring context by dispatcher servlet, I got an error inDelegatingFilterProxy filter:

java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:251)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.logging.log4j.core.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:66)


  • 如果我按 ContextLoaderListener创建春天上下文 我只有 404 错误因为没有servlet

    如果我通过servlet和&创建弹簧上下文监听器我有重复的上下文,因此所有bean都是重复的,包括带有请求映射的控制器,双重执行 @Scheduled 方法等。

    If I create spring context by both servlet & listener I have duplicated context, so all beans are duplicated, including controllers with request mappings, double-executing @Scheduled methods etc.

    如何创建高级弹簧应用程序(包括大量过滤器等)而不重复上下文?

    我的web.xml:

    <?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"
            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>MyWebApplication</display-name>
    
            <servlet>
                    <servlet-name>springDispatcher</servlet-name>
                    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                    <init-param>
                            <param-name>contextConfigLocation</param-name>
                            <param-value>/WEB-INF/spring.xml</param-value>
                    </init-param>
                    <load-on-startup>1</load-on-startup>
            </servlet>
    
            <servlet-mapping>
                    <servlet-name>springDispatcher</servlet-name>
                    <url-pattern>/</url-pattern>
            </servlet-mapping>
    
            <listener>
                    <listener-class>
                      org.springframework.web.context.ContextLoaderListener
                 </listener-class>
            </listener>
    
            <context-param>
                    <param-name>contextConfigLocation</param-name>
                    <param-value>
                            /WEB-INF/spring.xml
                    </param-value>
            </context-param>
    
            <!-- UTF-8 -->
            <filter>
                 <filter-name>encoding-filter</filter-name>
                 <filter-class>
                     org.springframework.web.filter.CharacterEncodingFilter
                 </filter-class>
                 <init-param>
                     <param-name>encoding</param-name>
                     <param-value>UTF-8</param-value>
                 </init-param>
                 <init-param>
                 <param-name>forceEncoding</param-name>
                 <param-value>true</param-value>
                 </init-param>
             </filter>
    
        <filter-mapping>
            <filter-name>encoding-filter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
             <!-- Spring Security -->
            <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>
    
    </web-app>
    


    推荐答案

    如果使用弹簧相关的servlet过滤器并使用mvc控制器,那么你需要两个:

    if you use spring related servlet filters and also use mvc controllers, then you need both:


    • ContextLoaderListener AND

    • DispatcherServlet-spring-configuration

    (请参阅 ContextLoaderListener?

    两者都创建自己的servlet上下文。
    ContextLoaderListener创建父上下文(有时称为内部上下文)。 DispatcherServlet创建一个子上下文(父上下文)(有时称为外部上下文)。
    子上下文的bean可以访问父上下文的bean,但不能反过来。

    Both create their own servlet context. The ContextLoaderListener create the parent-context (sometimes called the inner-context). And the DispatcherServlet create a child-context (of the parent context) (sometimes called the outer-context). The beans of the child-context can access the beans of the parent-context, but not the other way around.

    在一个不太简单的Web应用程序中你需要两个上下文,因为有许多servlet过滤器需要一个已经创建的spring上下文。另一方面,所有控制器的东西都需要一个ServletContext,而这只是由Dispatcher Servlet创建的。

    In a not too simple web application you need both contexts, because the there are many servlet filters that requires an already created spring context. On the other hand, all the controller stuff needs a ServletContext, and this is only created by the Dispatcher Servlet.

    另一点是,你不应该创建每个bean两次(有时这不是问题,有时则是这样)。所以你需要有两个弹簧配置,一个用于内部上下文,一个用于另一个上下文。并且你需要为每个bean决定它是属于内部还是外部。

    Another point is, that you should not have every bean created twice (sometimes this is no problem, other times it is). So you need to have two spring configurations, one for the inner context, one for the other context. And you need to decide for every bean whether it belongs to the inner or to the outer context.

    经验法则是:将每个东西放在内部上下文中,除了那些需要Servlet上下文或者与Web前端密切相关的东西,比如MVC-Controllers,Tiles配置...... ....

    The rule of thumb is: put every thing in the inner context, except that stuff that requires a Servlet context or is heavily tied to the Web-frontend, like MVC-Controllers, Tiles configuration, ....

    这篇关于由于加倍的上下文(servlet + ContextLoaderListener),所有Spring Framework bean都会重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆