为什么Spring Context被加载两次?

时间:2012-07-10 08:17:09

标签: java spring

我有Spring和Spring安全的Web项目。 我的web.xml:

    <web-app 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_3_0.xsd"
         version="3.0" >
        <display-name>BillBoard
        </display-name>
        <session-config>
            <session-timeout>
                30
            </session-timeout>
        </session-config>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <listener>
            <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
        </listener>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:security-config.xml classpath:billboard-servlet.xml</param-value>
        </context-param>
        <servlet>
            <servlet-name>billboard</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:security-config.xml classpath:billboard-servlet.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>

        </servlet>
        <servlet-mapping>
            <servlet-name>billboard</servlet-name>
            <url-pattern>*.html</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>
    </web-app>

在服务器日志中,我看到Spring上下文被加载了两次(spring bean初始化,数据库创建......)。 DispatcherServlet首次执行此操作,并在secont时间执行ContextLoaderListener。我该如何解决?

this教程中,我看到如果出现了contextParam,则不需要servlet init-params。但是,如果我删除init params,我有错误:“org.apache.catalina.LifecycleException:org.apache.catalina.LifecycleException:java.io.FileNotFoundException:无法打开ServletContext资源[/WEB-INF/billboard-servlet.xml] ”。 Dispather servlet在默认位置查找上下文配置。

5 个答案:

答案 0 :(得分:6)

您仍然需要servlet的上下文:

  

在初始化DispatcherServlet时,Spring MVC在Web应用程序的WEB-INF目录中查找名为[servlet-name] -servlet.xml的文件,并创建在那里定义的bean,覆盖定义的任何bean的定义全球范围内的同名。

您无需在context-param {。}}中将其加载为ContextLoaderListener

只需将security-config.xml保留为context-param(它必须转到那里,因为每个应用程序的安全性是全局的),而billboard-servlet.xml作为您的servlet的contextConfigLocation,它应该工作

答案 1 :(得分:3)

我有同样的问题,原因是:

<load-on-startup>1</load-on-startup

答案 2 :(得分:2)

这是两个独立的方法来做同样的事情。例如,删除ContextLoaderListener

答案 3 :(得分:1)

由于您有delegatingFilterProxy春天,如果您放弃contextLoaderLister,您将获得以下异常。

java.lang.IllegalStateException: No WebApplicationContext found: 
no   ContextLoaderListener registered?

所以通过contextLoaderLister和billboard-servlet.xml通过调度程序servlet加载security-config.xml。

答案 4 :(得分:0)

在XML中配置spring MVC框架配置时,可以将其配置如下:

<!-- for Spring context loader -->
<servlet>
    <servlet-name>billboard</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:security-config.xml classpath:billboard-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>

</servlet>

此配置将导致IoC容器初始化两次。

您应该将默认的servlet名称[广告牌]更改为其他名称,以解决此问题。

因为您的调度程序Servlet使用默认上下文名称空间[servlet的名称] -servlet.xml (对于billboard-servlet.xml),Spring MVC会自动加载它。

有关更多详细信息,请参见:https://www.conqtech.com/blog/?p=85