为什么我的Spring @Async bean方法不是异步执行的?

时间:2015-03-09 14:17:40

标签: java spring asynchronous spring-boot

我有一个Springboot应用程序,我正在尝试在控制器方法内的bean类上执行异步方法。问题是我的@Async方法没有异步执行。执行将暂停,直到方法完成。

谁能告诉我我错过了什么?

这是我的应用程序类:

@SpringBootApplication
@EnableAsync
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {

            @Override
            public void customize(Connector connector) {

                connector.setPort(9000);
                connector.setAsyncTimeout(60000);
            }
        });
        return factory;
    }
 }

这是我的bean类:

public class LongProcess {

    @Async
    public Future<String> call() {
        try {
            System.out.println("Sleeping now...");
            Thread.sleep(10000);
            return new AsyncResult<String>("Hey");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

}

我的配置类:

@Configuration
@EnableAsync
public class LongProcessConfiguration implements AsyncConfigurer {

    @Bean
    public LongProcess longProcessBean() {
        return new LongProcess();
    }

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setMaxPoolSize(10);
        taskExecutor.setThreadNamePrefix("LULExecutor-");
        taskExecutor.initialize();
        return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }

}

我的控制器方法:

@RequestMapping("/utilities/longProcess")
    public String longProcess() {

        System.out.println("Starting long process...");
        CsvFileDifferConfiguration context = new CsvFileDifferConfiguration();
        LongProcess process = context.longProcessBean();
        Future<String> result = process.call();
        System.out.println("Done!");
        return "{success: 1}";

    }

遗憾的是,此请求不会立即返回(我不关心结果)。该方法被成功调用,但不在后台调用。知道我可能会缺少什么吗?

作为测试,如果我将控制器方法更改为等待结果,则永远不会输入等待块:

@RequestMapping("/utilities/longProcess")
    public String longProcess() throws InterruptedException {

        System.out.println("Starting long process...");
        CsvFileDifferConfiguration context = new CsvFileDifferConfiguration();
        LongProcess process = context.longProcessBean();
        Future<String> result = process.call();
        while (!(result.isDone())) {
            Thread.sleep(1); //10-millisecond pause between each check
            System.out.println("Waiting for Long Process...");
        }
        System.out.println("Done!");
        return "{success: 1}";

    }

1 个答案:

答案 0 :(得分:1)

您使用CDI时出错。 如果您使用Spring Container管理对象,则必须使用ApplicationContext或其@Autowired等功能进行交易。

代码

CsvFileDifferConfiguration context = new CsvFileDifferConfiguration();

错了。

由于您将LongProcess定义为@Bean,您只需将其注入@Controller

@Autowired
privete LongProcess process;

并像以前一样使用它。

直接使用对象(例如new)会丢失dependency injection功能。

请阅读更多Spring文档。