Spring @Async Not Working

  1. Try adding proxy-target-class="true" to all <*:annotation-driven/> elements that support this attribute.
  2. Check if your method annotated with @Async is public.

With the help of this excellent answer by Ryan Stewart, I was able to figure this out (at least for my specific problem).

In short, the context loaded by the ContextLoaderListener (generally from applicationContext.xml) is the parent of the context loaded by the DispatcherServlet (generally from *-servlet.xml). If you have the bean with the @Async method declared/component-scanned in both contexts, the version from the child context (DispatcherServlet) will override the one in the parent context (ContextLoaderListener). I verified this by excluding that component from component scanning in the *-servlet.xml -- it now works as expected.


For me the solution was to add @EnableAsync on my @Configuration annotated class:

@Configuration
@ComponentScan("bla.package")
@EnableAsync
public class BlaConfiguration {

}

Now the class in package bla.package which has @Async annotated methods can really have them called asynchronously.


Jiří Vypědřík's answer solved my problem. Specifically,

  1. Check if your method annotated with @Async is public.

Another useful information from Spring tutorials https://spring.io/guides/gs/async-method/:

Creating a local instance of the FacebookLookupService class does NOT allow the findPage method to run asynchronously. It must be created inside a @Configuration class or picked up by @ComponentScan.

What this means is that if you had a static method Foo.bar(), calling it in that manner wouldn't execute it in async, even if it was annotated with @Async. You'll have to annotate Foo with @Component, and in the calling class get an @Autowired instance of Foo.

Ie, if you have a annotated method bar in class Foo:

@Component
class Foo { 
   @Async
   public static void bar(){ /* ... */ }

   @Async
   public void bar2(){ /* ... */ }
}

An in your caller class:

class Test {

  @Autowired Foo foo;

  public test(){
     Foo.bar(); // Not async
     foo.bar(); // Not async
     foo.bar2(); // Async
  }

}

Edit: Seems like calling it statically also doesn't execute it in async.

Hope this helps.