Spring @Scheduled 使用注释时执行任务两次

发布于 2024-09-03 13:05:44 字数 1001 浏览 6 评论 0原文

我已经使用 Spring @Scheduled 注释创建了任务,但由于某种原因它执行任务两次。我的Spring框架版本是3.0.2。

@Service
public class ReportService {

    @Scheduled(fixedDelay=1000 * 60 * 60* 24)
    @Transactional
    public void dailyReportTask()
    {
        ... code here ...
    }

}

这是我的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    <task:scheduler id="taskScheduler" />
    <task:executor id="taskExecutor" pool-size="1" />
    <task:annotation-driven executor="taskExecutor"
        scheduler="taskScheduler" />
</beans>

I have made task using Spring @Scheduled annotation, but for some reason it is executing task twice. My Spring Framework version is 3.0.2.

@Service
public class ReportService {

    @Scheduled(fixedDelay=1000 * 60 * 60* 24)
    @Transactional
    public void dailyReportTask()
    {
        ... code here ...
    }

}

Here is my XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    <task:scheduler id="taskScheduler" />
    <task:executor id="taskExecutor" pool-size="1" />
    <task:annotation-driven executor="taskExecutor"
        scheduler="taskScheduler" />
</beans>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

狼性发作 2024-09-10 13:05:44

这是因为上下文侦听器而发生的,

只需从 web.xml 中删除

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

它就应该可以工作。

it is happening because of context listener

Just remove

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

from web.xml it should work.

别把无礼当个性 2024-09-10 13:05:44

我也遇到了同样的问题,最终发现问题是由于在 root context 以及 servlet context 中创建 bean 造成的。

因此,要解决此问题,您需要将 bean 的创建分离到适当的上下文中。

这个答案很好地解释了如何做到这一点,并且解决了我的问题。

I had this same problem, and I eventually found out that the problem was occurring as a result of the beans being created in the root context as well as the servlet context.

So, to fix this, you need to separate the creation of the beans into the appropriate contexts.

This answer explains really well how to that and was what fixed my problem.

我的痛♀有谁懂 2024-09-10 13:05:44

根据这篇文章: http://www.vodori.com/blog/spring3scheduler.html

Spring 3.0.0 版本有一个错误,其中
带有任务调度程序的网络应用程序
最终执行预定的方法
两次。这已解决
春季3.0.1。

报告了另一个影响版本的错误:3.0.2
https://jira.springsource.org/browse/SPR-7216

应该修复版本:3.0.3。

According to this post: http://www.vodori.com/blog/spring3scheduler.html

Spring 3.0.0 Release had a bug where
web apps with a task scheduler would
end up executing scheduled methods
twice. This has been resolved in
Spring 3.0.1.

There has been another bug reported which affects Version/s: 3.0.2
https://jira.springsource.org/browse/SPR-7216

Which should be fixed in Version/s: 3.0.3.

兔姬 2024-09-10 13:05:44

我最近刚刚遇到这个问题,这是由于我的应用程序通过eclipse在Tomcat中部署了两次而引起的。问题是我已经在 Eclipse 中重命名了我的应用程序,但“org.eclipse.wst.common.component”.settings 文件中指定的“wb-module deploy-name”仍然具有旧名称。

在 tomcat 管理器中,我可以看到有 2 个应用程序以不同的名称运行。

I just had this problem recently and it was caused by my app being deployed twice in Tomcat by eclipse. The problem was that I had renamed my application in eclipse but the "wb-module deploy-name" specified in the "org.eclipse.wst.common.component" .settings file still had the old name.

In the tomcat manager, I could see that I had 2 apps running with different names.

偏爱自由 2024-09-10 13:05:44

你实际上在哪里运行它?你的电脑?单服务器? 2 个负载平衡的应用程序服务器?

它可能在 (a) 你的电脑和 (b) 你的服务器上运行,所以它看起来就像运行了两次,如果你明白我的意思:它正确运行一次,只是在两个不同的位置。

Where are you actually running it? Your PC? Single server? 2 x load-balanced app servers?

Could be it's running on (a) your PC and (b) your server, so it just looks like it's running twice, if you see what I mean: it's correctly running once, just on two distinct locations.

友谊不毕业 2024-09-10 13:05:44

检查配置文件中是否有任何手动调度程序配置(通过 Java/XML)。我遇到了同样的问题,我发现我的配置加载了我的调度程序类两次:

在Java中:

package com.mywork.br.myschuedulerpackage;
{...}
@Configuration
@EnableScheduling
public class SchedulerConfiguration {

    @Bean
    public CTXDataImporterScheduler ctxDataImporterScheduler() {
        return new CTXDataImporterScheduler();
    }
}

在XML applicationContext.xml中:

<context:component-scan base-package="com.mywork.br.myschuedulerpackage" />

在我的调度程序类中,我有@Component注释,它被组件扫描捕获并加载了一个第二次导致 @scheduler 方法被执行两次。
我删除了 Java 配置,现在运行良好!

Check if you have any manual scheduler config in your configuration files (through Java/XML). I'ved the same problem, and I discover that my config was loading my scheduler class twice:

In Java:

package com.mywork.br.myschuedulerpackage;
{...}
@Configuration
@EnableScheduling
public class SchedulerConfiguration {

    @Bean
    public CTXDataImporterScheduler ctxDataImporterScheduler() {
        return new CTXDataImporterScheduler();
    }
}

In XML applicationContext.xml:

<context:component-scan base-package="com.mywork.br.myschuedulerpackage" />

And in my scheduler class, I had @Component annotation thats was catch by the component scan and loaded a second time causing the @scheduler methods being executed twice.
I removed the Java config and then is working well now!

终止放荡 2024-09-10 13:05:44

要解决 @Scheduled 方法的两次工作问题,只需从 web.xml 中删除 ContextLoaderListener (如果您使用基于 web.xml 的应用程序):

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

或者如果您使用基于WebApplicationInitializer的应用程序,只需删除添加ContextLoaderListener的字符串:

package com.dropbox.shortener.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

public class DropboxShortenerWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfig.class);

        // (!) Delete the next string
        // container.addListener(new ContextLoaderListener(rootContext));

        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(WebConfig.class);

        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        setupCharEncodingFilter(container);
    }

    private void setupCharEncodingFilter(ServletContext container) {
        container.setInitParameter("defaultHtmlEscape", "true");

        FilterRegistration charEncodingFilterReg = container.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);
        charEncodingFilterReg.setInitParameter("encoding", "UTF-8");
        charEncodingFilterReg.setInitParameter("forceEncoding", "true");
        charEncodingFilterReg.addMappingForUrlPatterns(null, false, "/*");
     }
}

To solve twice-working of @Scheduled method just delete ContextLoaderListener from you web.xml (if you use web.xml-based application):

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Or if you use WebApplicationInitializer-based application just delete a string that adds ContextLoaderListener:

package com.dropbox.shortener.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

public class DropboxShortenerWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfig.class);

        // (!) Delete the next string
        // container.addListener(new ContextLoaderListener(rootContext));

        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(WebConfig.class);

        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        setupCharEncodingFilter(container);
    }

    private void setupCharEncodingFilter(ServletContext container) {
        container.setInitParameter("defaultHtmlEscape", "true");

        FilterRegistration charEncodingFilterReg = container.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);
        charEncodingFilterReg.setInitParameter("encoding", "UTF-8");
        charEncodingFilterReg.setInitParameter("forceEncoding", "true");
        charEncodingFilterReg.addMappingForUrlPatterns(null, false, "/*");
     }
}
三五鸿雁 2024-09-10 13:05:44

在您的 bean 上使用 @Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)

Use @Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) on your bean

因为看清所以看轻 2024-09-10 13:05:44
Disabling below will work.
 <!-- <listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener> -->
Disabling below will work.
 <!-- <listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener> -->
新人笑 2024-09-10 13:05:44

我建议的一种解决方案是像这样进行组件扫描

- 在应用程序上下文中

<context:component-scan base-package="com.abc.cde.dao" />

在 yourservlet-servlet.xml 中

<!-- package that had all the @Controller classes -->

我这样只有在加载 web.xml 时才会加载 servlet
可以对任务执行类似的操作

One solution I would suggest is to do component scat like this

-In application context

<context:component-scan base-package="com.abc.cde.dao" />

In yourservlet-servlet.xml

<!-- package that had all the @Controller classes -->

I this way the servlet is only loaded if the web.xml is loaded
Similar can be done for task

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文