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

Sot*_*lis 4 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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

nic*_*ild 16

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

如果您希望方法在应用程序启动时运行,那么您应该使用@PostConstruct注释(在非延迟加载的bean上).如果你需要一个方法来异步运行,那么你将有更棘手一点,因为你同时使用@PostConstruct,并@Async同时(如在25.5.2最后一段提到在这里).

编辑:

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

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