升级到Spring Boot 1.3.3后,@ Async无法正常工作

dbu*_*ush 7 java spring asynchronous spring-boot

我有一个在Spring Boot 1.2.3下运行的应用程序,它使用带注释的方法@Async.到目前为止,它一直在正常工作.

升级到Spring Boot 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");
    }

}
Run Code Online (Sandbox Code Playgroud)

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

在1.2.3下,方法中的日志语句将start它们显示为在线程中运行myTaskExecutor-1.在1.3.3下,相同的日志显示它们在线程中运行main.

知道这里可能有什么问题吗?

iva*_*nok 2

您需要将 bean 工厂方法放置在注释为 @Configuration 的其他类中。这样就可以使用Executor来执行@Async方法。

@Configuration
@EnableAsync
public class AsyncConfig {
   @Bean(name = "myTaskExecutor")
   public ThreadPoolTaskExecutor myTaskExecutor() {
      return new ThreadPoolTaskExecutor();
   }
}
Run Code Online (Sandbox Code Playgroud)