java 为什么 Spring Context 被加载两次?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11409237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why Spring Context is loaded twice?
提问by Balconsky
I have web project with Spring and Spring security. My web.xml:
我有带有 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>
In server logs I see Spring context is loaded twice (spring bean initialization, database createtion...). At first time DispatcherServlet does it, and at the secont time ContextLoaderListener. How can I fix it?
在服务器日志中,我看到 Spring 上下文被加载了两次(spring bean 初始化、数据库创建...)。第一次 DispatcherServlet 执行它,第二次执行 ContextLoaderListener。我该如何解决?
In thistutorial I see that if contextParam is presented then servlet init-params are not required. But if I remove init params I have error: "org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/billboard-servlet.xml]". Dispather servlet finds context-configuration in default location.
在本教程中,我看到如果提供了 contextParam,则不需要 servlet init-params。但是如果我删除初始化参数我有错误:“org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.io.FileNotFoundException: 无法打开 ServletContext 资源 [/WEB-INF/billboard-servlet.xml] ”。Dispather servlet 在默认位置找到上下文配置。
回答by soulcheck
You still need a context for your servlet:
您仍然需要一个 servlet 的上下文:
Upon initialization of a DispatcherServlet, Spring MVC looks for a file named [servlet-name]-servlet.xml in the WEB-INF directory of your web application and creates the beans defined there, overriding the definitions of any beans defined with the same name in the global scope.
在初始化 DispatcherServlet 时,Spring MVC 会在您的 Web 应用程序的 WEB-INF 目录中查找名为 [servlet-name]-servlet.xml 的文件,并创建在那里定义的 bean,覆盖使用相同名称定义的任何 bean 的定义在全球范围内。
You don't need to load it as context-param
in the ContextLoaderListener
though.
你不需要像context-param
在那样加载它ContextLoaderListener
。
Just leave the security-config.xml
as context-param
(it has to go there, as security is global per application), and billboard-servlet.xml
as contextConfigLocation
of your servlet and it should work.
刚刚离开security-config.xml
的context-param
(它有去那里,因为安全是每个应用程序的全球性),并billboard-servlet.xml
为contextConfigLocation
你的servlet的,它应该工作。
回答by Stefan
I had the same issue and the reason was:
我有同样的问题,原因是:
<load-on-startup>1</load-on-startup
<load-on-startup>1</load-on-startup
回答by Marko Topolnik
These are two independent methods to do the same thing. Drop the ContextLoaderListener
, for example.
这是两种独立的方法来做同样的事情。ContextLoaderListener
例如,删除。
回答by Bharath
Since you have spring delegatingFilterProxy
, if you drop contextLoaderLister
you will get the below exception.
由于您有 spring delegatingFilterProxy
,如果您放弃,contextLoaderLister
您将获得以下异常。
java.lang.IllegalStateException: No WebApplicationContext found:
no ContextLoaderListener registered?
So load security-config.xml via contextLoaderLister and billboard-servlet.xml via dispatcher servlet.
因此,通过 contextLoaderLister 加载 security-config.xml,通过调度程序 servlet 加载 billboard-servlet.xml。
回答by aamir
When you configure the spring MVC framework configuration in the XML, you may configure it as bellow:
在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>
this configuration will cause the IoC container initialize twice.
此配置将导致 IoC 容器初始化两次。
You should change the default servlet name[billboard] to others to solve this problem.
您应该将默认 servlet 名称 [billboard] 更改为其他名称以解决此问题。
Because your dispatcher servlet is using the default context namespace [name of servlet]-servlet.xml (in the case billboard-servlet.xml) then Spring MVC will automatically load it.
因为您的调度程序 servlet 使用默认上下文命名空间 [servlet 的名称]-servlet.xml(在 billboard-servlet.xml 的情况下),那么 Spring MVC 将自动加载它。
For more details see: https://www.conqtech.com/blog/?p=85
更多详情请见:https: //www.conqtech.com/blog/?p=85