Spring @Scheduled выполняет задачу дважды при использовании аннотаций - PullRequest
7 голосов
/ 31 мая 2010

Я выполнил задачу, используя аннотацию Spring @Scheduled, но по какой-то причине она выполняет задачу дважды Моя версия Spring Framework 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>

Ответы [ 10 ]

5 голосов
/ 10 июля 2014

это происходит из-за прослушивателя контекста

Просто удалите

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

из web.xml должно работать.

2 голосов
/ 24 февраля 2015

У меня была такая же проблема, и в конце концов я обнаружил, что проблема возникает в результате создания bean-компонентов в root context и servlet context.

Итак, чтобы это исправить, вам нужно разделить создание bean-компонентов на соответствующие контексты.

Этот ответ очень хорошо объясняет, как это сделать, и это помогло решить мою проблему.

1 голос
/ 10 июля 2014

Я только недавно столкнулся с этой проблемой, и она была вызвана тем, что мое приложение дважды развертывалось в Tomcat при помощи eclipse. Проблема состояла в том, что я переименовал свое приложение в eclipse, но «wb-module deploy-name», указанное в файле «org.eclipse.wst.common.component» .settings, все еще имело старое имя.

В диспетчере Tomcat я увидел, что у меня запущено 2 приложения с разными именами.

1 голос
/ 13 апреля 2011

Согласно этому посту: http://www.vodori.com/blog/spring3scheduler.html

Spring 3.0.0 Release имел ошибку, при которой веб-приложения с планировщиком задач в конечном итоге выполнение запланированных методов дважды. Это было решено в Spring 3.0.1.

Произошла другая ошибка, которая затрагивает версию / s: 3.0.2 https://jira.springsource.org/browse/SPR-7216

Что должно быть исправлено в версии / версиях: 3.0.3.

0 голосов
/ 20 апреля 2016
Disabling below will work.
 <!-- <listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener> -->
0 голосов
/ 15 сентября 2015

Используйте @Scope (value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) для вашего компонента

0 голосов
/ 31 мая 2015

Чтобы решить двойную работу метода @Scheduled, просто удалите ContextLoaderListener из вас web.xml (если вы используете приложение на основе 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, "/*");
     }
}
0 голосов
/ 28 мая 2015

Проверьте, есть ли у вас конфигурация планировщика вручную в ваших файлах конфигурации (через 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 и теперь работает хорошо!

0 голосов
/ 01 августа 2011

Одно из решений, которое я бы предложил, это сделать компонент scat следующим образом:

-В контексте приложения

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

В yourservlet-servlet.xml

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

В этом случае сервлет загружается только в том случае, если загружен файл web.xml. Подобное можно сделать для задачи

0 голосов
/ 31 мая 2010

Где вы на самом деле запускаете его? Ваш компьютер? Один сервер? 2 сервера приложений с балансировкой нагрузки?

Может быть, он работает на (а) вашем компьютере и (б) на вашем сервере, поэтому он выглядит так, как будто он работает дважды, если вы понимаете, о чем я: он работает правильно один раз, только в двух разных местах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...