考虑以下代码片段:
@Controller
public class RestController {
@Scheduled(cron = "0 0 */* * * ?") // run every hour
public void runMeHourly() {
LOGGER.debug("RestController#runMeHourly triggered to run at: " + System.currentTimeMillis());
// Do your hourly work here
}
}
当我在J2EE web服务器上部署这个控制器时,我看到RestController#runMeHourly()
in方法每小时触发两次。
我在spring文档调度中找到了类似的参考。
上面写着:
确保您没有在运行时初始化同一个@Scheduled注释类的多个实例,除非您确实想对每个这样的实例调度回调。与此相关的是,请确保不要在带有@Scheduled注释并在容器中注册为常规Spring bean的bean类上使用@Configurable:否则您将获得双重初始化,一次通过容器,一次通过@Configurable方面,导致每个@Scheduled方法被调用两次。
这有关系吗?这是否意味着我需要从RestController
之外调度方法runMeHourly()
?
[编辑1:看起来@可配置的是别的东西,而不是对问题做出贡献,我没有在任何地方使用它。所以一定有其他原因导致这种行为]
[编辑2:
]我的web . xml。
<web-app>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>com.company.module.ModuleContextListener</listener-class>
</listener>
</web.xml>
mvc-dispatcher-servlet.xml
<beans>
<mvc:annotation-driven />
<task:annotation-driven />
<context:component-scan base-package="com.company" />
<import resource="module/module-servlet.xml"/>
</beans>
模块/module-servlet.xml
<beans>
<context:component-scan base-package="com.company.module"/>
</beans>
]
com.company.module.ModuleContextListener
强制DispatcherServlet
查找根应用程序上下文,并且由于根应用程序上下文与mvc-dispatcher-servlet.xml
相同,因此它被加载两次。一次作为根上下文,另一次作为DispatcherServlet的名称mvc-dispatcher
。
将根上下文xml mvc-dispatcher-servlet.xml
重命名为applicationContext.xml
,并添加一个空的mvc-dispatcher-servlet.xml
解决了这个问题。
感谢@6ton指出这一点