加载上下文后,Spring java config启动@Async方法

时间:2013-05-27 22:06:26

标签: java spring asynchronous

我需要一个POJO方法异步执行,所以我用@Async注释了它。我已使用正确的@EnableAsync@Configuration课程添加了@ComponentScan。这是一个小测试案例供您运行。

public class Test {
    public static void main(String[] args) throws InterruptedException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(MyConfig.class);
        context.refresh();
        Object o = context.getBean(AsyncBean.class);

        //((AsyncBean)o).doStuff();

        System.out.println(o);

    }

    @ComponentScan(basePackages = "my.package")
    @EnableAsync
    @Configuration
    // @EnableScheduling
    public static class MyConfig {
        @Bean
        public AsyncBean bean() throws InterruptedException {
            AsyncBean b = new AsyncBean();
            return b;
        }
    }

    public static class AsyncBean {
        //@Scheduled(fixedRate = 10000L, initialDelay = 1000L)
        @Async
        public void doStuff() throws InterruptedException {
            for (int i = 0; i < 5; i++) {
                System.out.println("async loop" + i + " -> " + Thread.currentThread().getId());
                Thread.sleep(1000L);
            }
        }
    }
}

上面的代码将加载AnnotationConfigApplicationContext并退出。但是,如果我取消注释//((AsyncBean)o).doStuff();,那么它将在一个单独的线程中运行。为什么在完全读取配置时,@Async方法无法启动?这就是我所期望的。

我已经留下了一些@Scheduled的东西,所以你可以自己尝试一下。在@Scheduled的情况下,带注释的方法立即被触发(在初始延迟之后)。

我需要为Spring实现一些其他东西才能知道它必须启动我的@Async方法吗?

1 个答案:

答案 0 :(得分:15)

@Async无意在加载ApplicationContext后运行。它旨在在调用时以异步方式运行带注释的方法。

如果您希望方法在应用程序启动时运行,那么您应该使用@PostConstruct注释(在非延迟加载的bean上)。如果您需要该方法以异步方式运行,那么您必须更加棘手,因为同时使用@PostConstruct@Asyncas noted in the last paragraph of 25.5.2 here)。

修改

@Async@Scheduled之间的差异可能不是documentation中最明显的差异。通常,@Scheduled用于指示何时应该发生特定方法的下一次调用,并且通常是周期性的。 @Async用于异步运行方法,也就是说,该方法将在启动后台线程后立即返回以执行方法的工作。

令人困惑的部分是后台线程。他们都使用一个,但他们尝试做的事情的性质是不同的(定期背景工作通常是非用户交互式的,而不是通常由用户发起的一次性背景工作)。