次の3つのクラスがあります。
ComponantA
package mytest.spring.test.spring;
import org.Apache.log4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ComponentA {
Logger log = Logger.getLogger(ComponentB.class);
@Scheduled(fixedRate=2000)
public void sayHello() {
for(int i=1 ; i<=5 ; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.info("Hello from ComponentA " + i);
}
}
}
ComponentB
package mytest.spring.test.spring;
import org.Apache.log4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ComponentB {
Logger log = Logger.getLogger(ComponentB.class);
@Scheduled(fixedRate=2000)
public void sayHello() {
for(int i=1 ; i<=3 ; i++) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
log.info("Hello from ComponentB " + i);
}
}
}
MyApplication
package mytest.spring.test.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
実行すると、次の出力が得られます。
Hello from ComponentA 1
Hello from ComponentA 2
Hello from ComponentA 3
Hello from ComponentA 4
Hello from ComponentA 5
Hello from ComponentB 1
Hello from ComponentB 2
Hello from ComponentB 3
Hello from ComponentA 1
Hello from ComponentA 2
Hello from ComponentA 3
Hello from ComponentA 4
Hello from ComponentA 5
Hello from ComponentB 1
Hello from ComponentB 2
Hello from ComponentB 3
...
2つのScheduledメソッドを並行して実行する必要がありますが、これは、取得した出力によると明らかに原因ではありません。 @ScheduleアノテーションにカスタムTaskExecutorを提供できるはずであり、それを使用して必要なスレッド数を定義できるはずだと読みました...
私は正しいですか?この情報を提供する方法が見つかりません。
ドキュメント は明確に次のように述べています:
デフォルトでは、関連付けられたスケジューラ定義を検索します。コンテキスト内の一意の
TaskScheduler
Bean、または「taskScheduler」という名前のTaskScheduler
Bean。ScheduledExecutorService
Beanに対しても同じルックアップが実行されます。 2つのどちらも解決できない場合は、ローカルのシングルスレッドのデフォルトスケジューラが作成され、レジストラ内で使用されます。より詳細な制御が必要な場合は、@ ConfigurationクラスでSchedulingConfigurerを実装できます。これにより、基盤となるScheduledTaskRegistrarインスタンスにアクセスできます。たとえば、次の例は、スケジュールされたタスクの実行に使用されるエグゼキュータをカスタマイズする方法を示しています。
@Configuration @EnableScheduling public class AppConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(taskExecutor()); } @Bean(destroyMethod="shutdown") public Executor taskExecutor() { return Executors.newScheduledThreadPool(100); } }