Why does Spring 4 only allow one TaskScheduler in a context?

后端 未结 3 1104
青春惊慌失措
青春惊慌失措 2021-02-04 08:41

We have a Spring web application we\'re porting from Spring 3.2 to Spring 4. Our application has several sub-contexts assembled into a single runtime context when the web appli

相关标签:
3条回答
  • 2021-02-04 08:50

    Just add bean to your config:

     @Bean()
     public ThreadPoolTaskScheduler taskScheduler() {
        return new ThreadPoolTaskScheduler();
     }
    
    0 讨论(0)
  • 2021-02-04 09:10

    You need to explicitly specify which scheduler to use with @Scheduled annotations. Just add scheduler attribute:

    <task:annotation-driven scheduler="commonScheduler" mode="aspectj" />
    <task:scheduler id="commonScheduler" pool-size="5" />
    
    0 讨论(0)
  • 2021-02-04 09:11

    Yeah, this is a change in behavior for sure. It appears that the ScheduledAnnotationBeanPostProcessor now has a limit of 2 schedulers per context. I ran into this with Spring 4's new WebSocket message broker as it allocates 2 schedulers for the Simple STOMP broker and the SockJS adapter. When I added my own, it totally dorked out with the same message you got. I found it rather annoying that I had to find out this limitation via errors rather documentation. This gotcha doesn't appear to be described in the Spring 4 documentation.

    The solution is to create your own SchedulingConfigurer that manages its own TaskScheduler. I suspect that the reason is that there is only one and additional TaskScheduler implementations need to be added in order to isolate them from one another. I did something like so:

    @Configuration
    @EnableScheduling
    public class MySchedulingConfigurer implements SchedulingConfigurer
    {
       @Bean
       public TimedThingy timedThingy()
       {
          return new TimedThingy();
       }
    
      @Bean()
      public ThreadPoolTaskScheduler taskScheduler() {
         return new ThreadPoolTaskScheduler();
      }
    
      @Override
      public void configureTasks(ScheduledTaskRegistrar taskRegistrar)
      {
          taskRegistrar.setTaskScheduler(taskScheduler());
          taskRegistrar.addFixedRateTask(new Runnable()
          {
             public void run()
             {
                timedThingy().sendIt();
             }
          }, 1000);
      }
    }
    

    Once I did that, the issue went away and things worked as desired. The down side is that you can't use annotations like @Scheduled, etc.. But you do gain more control and things work. Hope this helps.

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