Java 为什么我的Spring ContextRefresh事件被调用了两次?

Java 为什么我的Spring ContextRefresh事件被调用了两次?,java,spring,spring-mvc,Java,Spring,Spring Mvc,我注册了一个Spring ApplicationListener bean来侦听ContextRefreshed事件。然而,出于某种奇怪的原因,在上下文初始化完成时,我得到了对onApplicationEvent(ContextRefreshedEvent)方法的两个调用。这是正常行为还是表明我的配置有问题?我正在使用Jetty 8作为Servlet容器 我的相关web.xml配置如下 <context-param> <param-name>contextConf

我注册了一个Spring ApplicationListener bean来侦听ContextRefreshed事件。然而,出于某种奇怪的原因,在上下文初始化完成时,我得到了对onApplicationEvent(ContextRefreshedEvent)方法的两个调用。这是正常行为还是表明我的配置有问题?我正在使用Jetty 8作为Servlet容器

我的相关web.xml配置如下

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/config/spring/spring-config.xml</param-value>
</context-param>
<servlet>
    <servlet-name>Spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
    <servlet-name>Spring</servlet-name>
    <url-pattern>/service/*</url-pattern>
</servlet-mapping>

上下文配置位置
/WEB-INF/config/spring/spring-config.xml
春天
org.springframework.web.servlet.DispatcherServlet
上下文配置位置
1.
org.springframework.web.context.ContextLoaderListener
春天
/服务/*
谢谢

它看起来像一只虫子


如果您使用的是3.0,请在最新的可用版本3.05上试用

即使您没有为DispatcherServlet指定contextConfigLocation,它仍然会创建一个子上下文,第二个刷新事件是针对该上下文的。使用event.getApplicationContext()找出事件的上下文

我也有这个问题,但已经解决了。我将数据源注入到我的DAO中(并用它实例化一个JdbcTemplate)……但是我还为JdbcTemplate配置了一个Springbean


我应该在我的DAO中注入jdbcTemplate…这样可以避免重复

这也发生在我身上,在另一个事件侦听器上。(
ApplicationListener

有趣的答案是:

ContextLoaderListener是可选的 启动Spring应用程序而无需配置 ContextLoaderListener…只是基本的最小web.xml 调度员服务


好的,我们使用的是3.0.4,所以我将尝试3.0.5并报告我的发现。呸,升级到3.0.5,这仍然是一个问题。即使是3.1也有同样的问题。就是它!使用ApplicationContext的
id
displayName
属性,我现在可以区分这两个事件。或者如果您@Autowire应用上下文(或实现ApplicationContextAware)您可以将该appContext与事件中的appContext进行比较。@Andre A noob的问题:如何从ContextRefreshedEvent访问ID或displayName?解决了这个问题。将ContextRefreshedEvent.getSource()强制转换为ApplicationContext,然后对其调用getDisplayName()/getId()。