私は、アプリケーションがSpringブート1.2.3の下で実行され、@Async
と注釈されたメソッドを使用しています。今日まで、それは適切に機能しています。Spring Boot 1.3.3にアップグレードした後に@Asyncが動作しない
Springブート1.3.3にアップグレードした後、@Async
とマークされたメソッドは、別のスレッドで呼び出されていません。
App.java:
package test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = { "test" })
@EnableAsync
public class App implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(App.class);
@Autowired
AsyncClass async;
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
public void run(String... arg0) throws Exception {
log.info("in run");
async.start();
log.info("done run");
}
}
AsyncClass.java:
package test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
@Component
public class AsyncClass {
private static final Logger log = LoggerFactory.getLogger(AsyncClass.class);
@Async("myTaskExecutor")
public void start() {
log.info("in async task");
try {
Thread.sleep(2000);
} catch (InterruptedException e) { }
log.info("done async task");
}
@Bean
public ThreadPoolTaskExecutor myTaskExecutor() {
ThreadPoolTaskExecutor bean = new ThreadPoolTaskExecutor();
bean.setCorePoolSize(1);
bean.setMaxPoolSize(1);
bean.setQueueCapacity(10);
bean.setThreadPriority(1);
bean.setWaitForTasksToCompleteOnShutdown(true);
return bean;
}
}
のpom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dbush</groupId>
<artifactId>async-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>async-test</name>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<!-- this is the only line that differs -->
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
ここ
は、問題を説明するサンプルプログラムです1.2.3では、ログstart
メソッドのステートメントはスレッドmyTaskExecutor-1
で実行中であることを示します。 1.3.3では、同じログがスレッドmain
で実行されていることを示しています。
何が間違っているのでしょうか?
ありがとうございました。この設定は、スタートアップ時に開始するスレッドを使った単純な例では機能しますが、フルプログラムにはこれらのうちの1つとWebリクエストを介して呼び出される2番目のタスクが含まれているので、 'ThreadPoolTaskExecutor' @ Configuration'クラスが最も簡単な解決策でした。 – dbush