Spring java配置启动@Async方法一旦上下文加载



我需要一个异步执行的POJO方法,所以我用@Async注释了它。我用适当的@ComponentScan@EnableAsync添加到我的@Configuration类中。这里有一个小测试用例供您运行。

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的情况下,带注释的方法立即被触发(即在初始延迟之后)。

还有什么我需要实现的春天知道它必须启动我的@Async方法?

@Async不打算在加载ApplicationContext之后运行。它旨在在调用带注释的方法时异步运行该方法。

如果你想让一个方法在应用程序启动时运行,那么你应该使用@PostConstruct注释(在非惰性加载bean上)。如果你需要异步运行该方法,那么你将不得不更狡猾一点,因为你同时使用@PostConstruct@Async(如25.5.2的最后一段所述)。

编辑:

@Async@Scheduled之间的差异从文档中可能不是最清楚的。一般来说,@Scheduled用于告诉何时应该发生对特定方法的下一次调用,并且通常是周期性的。@Async用于异步运行方法,也就是说,该方法将在启动后台线程完成该方法的工作后立即返回。

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

最新更新