Java Spring @Scheduled tasks executing twice

前端 未结 23 1546
清歌不尽
清歌不尽 2020-11-29 09:07

I have a simple test method here that is set to run every 5 seconds and it does, but looking at the System.out you can see it appears to be doing something odd.



        
相关标签:
23条回答
  • 2020-11-29 09:27

    I know the answer!!

    Don't init your Scheduled twice

    Loot at your web log :

    WebApplicationContext once and servlet once

    so in your servlet.xml don't do like this

    import resource="classpath:applicationContext.xml"
    
    0 讨论(0)
  • 2020-11-29 09:28

    If you look at the documentation, there is a note that explicitly calls out this phenomenon.

    The note is under section 25.5.1 at this link, and reads:

    Make sure that you are not initializing multiple instances of the same @Scheduled annotation class at runtime, unless you do want to schedule callbacks to each such instance. Related to this, make sure that you do not use @Configurable on bean classes which are annotated with @Scheduled and registered as regular Spring beans with the container: You would get double initialization otherwise, once through the container and once through the @Configurable aspect, with the consequence of each @Scheduled method being invoked twice.

    I understand that this is merely suggestion at this point, but I do not think we have enough information to diagnose the issue further.

    0 讨论(0)
  • 2020-11-29 09:29

    Had the same issue with my springboot-application, the Scheduler runs twice.

    Reason was, as mentioned multiple times in earlier comments, that the bean is initialized multiple times.

    My solution was:

    • Remove the @Component Annotation (on the Class which contains the @Scheduled method)
    • Manually add the Class which contains the @Scheduled Method into the ApplicationContext

    In the code- this was the change i´ve made:

    // @Component <------ Removed
    public class FileTransferScheduler {
    
        private final Logger logger = LoggerFactory.getLogger(FileTransferScheduler.class);
    
        @Autowired
        private ExtractorService extractorService;
    
        @Scheduled(cron = "* /1 * * * *")
        public void scheduleFileTransfer() {
    
            logger.info("Triggered cronjob to transfer new uploads to dms...");
            extractorService.extractTmcUploads();
        }
    
    }
    

    ...and then this change in the main method of the springboot-application:

    @EnableScheduling
    @SpringBootApplication
    public class InsidersExtractorApplication extends SpringBootServletInitializer {
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            // The Scheduler Class needs to be added manually, because it dont have to be defined as Bean
            return application.sources(InsidersExtractorApplication.class, FileTransferScheduler.class);
        }
    
        public static void main(String[] args) {
            SpringApplication.run(InsidersExtractorApplication.class, args);
        }
    
    }
    
    0 讨论(0)
  • 2020-11-29 09:30

    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.

    0 讨论(0)
  • 2020-11-29 09:30
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
             /WEB-INF/spring/root-context.xml
             /WEB-INF/spring/security/spring-security.xml
             /WEB-INF/spring/mongo/mongo-config.xml
             /WEB-INF/spring/appServlet/spring-context.xml
        </param-value>
    </context-param>
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/spring-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    

    That is my web.xml . So , you can see that "/WEB-INF/spring/appServlet/spring-context.xml" is loaded twice (once in context-param , once in servlet -> init-param ).

    0 讨论(0)
  • 2020-11-29 09:30

    I had the same problem, I tried all the suggested methods and nothing worked for me. Finally I was able to find the solution by removing the extension to 'SpringBootServletInitializer' and the 'configure' method of my WebApplication class and with this I stopped duplicating my Scheduled Task.

    0 讨论(0)
提交回复
热议问题