I need a POJO method to execute asynchronously, so I've annotated it with @Async
. I've added @EnableAsync
to my @Configuration
class with the proper @ComponentScan
. Here's a small test case for you to run.
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);
}
}
}
}
The code above will load the AnnotationConfigApplicationContext
and quit. If, however, I un-comment //((AsyncBean)o).doStuff();
, then that will run in a separate thread. Why is it that the @Async
method doesn't get started when the configuration is completely read? That's what I would expect.
I've left some @Scheduled
stuff above so you can try it yourself. In the case of @Scheduled
, the annotated method gets triggered right away (after initial delay that is).
Is there something else I need to implement for Spring to know it has to start my @Async
methods?
@Async
is not intended to be run after the loading of the ApplicationContext
. It is intended to run the annotated method asynchronously when it is invoked.
If you want a method to run at application startup, then you should use the @PostConstruct
annotation (on a non lazily loaded bean). If you need that method to run asynchronously, then you will have to be a bit more tricky, as you use both @PostConstruct
and @Async
simultaneously (as noted in the last paragraph of 25.5.2 here).
EDIT:
The differences between @Async
and @Scheduled
may not be the most clear from the documentation. In general, @Scheduled
is used to tell when the next invocation of a specific method should take place, and it typically periodic. @Async
is used to run a method asynchronously, that is, the method will return immediately after starting up a background thread to do the work of the method.
The confusing part for this is the background thread. They both use one, but the nature of what they are trying to do is different (periodic background work which is generally non user interactive vs one time background work typically initiated by a user).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With