14

I am using @Scheduled and it have been working fine, but can't get the @Async working. I tested it many times, and seems that it is making my method asynchronous. Is there any other thing, configuration, or parameter I am missing? I have one class that has two methods one, the method marked with @Scheduled, executes and calls the second one which has been marked with @Async.

Here is my config:

<!-- Scans within the base package of the application for @Components to configure as beans -->
<context:component-scan base-package="com.socialmeety" />
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager" />
<task:annotation-driven/>

<!-- Configures support for @Controllers -->
<mvc:annotation-driven />

<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/>
    <property name="suffix" value=".jsp"/>
</bean>

<dwr:configuration />
<dwr:annotation-config />
<dwr:url-mapping />
<dwr:controller id="dwrController" debug="true" />

<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

Thanks.

Betlista
  • 10,327
  • 13
  • 69
  • 110
  • you should provide some more info. (code snippets etc) – onigunn Oct 30 '10 at 21:19
  • don't have any exception it just doesn't make the method asynchronous. Any especial configuration to get it working? that is my question, will post my config to tell more about my env. I already have my @Scheduled working fine. –  Oct 30 '10 at 21:46

4 Answers4

40

As you're calling your @Async method from another method in the same object, you're probably bypassing the async proxy code and just calling your plain method, ie within the same thread.

One way of solving this is by making sure your call to the @Async method is from another object. See comments at end of this article: http://groovyjavathoughts.blogspot.com/2010/01/asynchronous-code-with-spring-3-simple.html

But it gets messy doing things like that, so you could just autowire the TaskScheduler, wrap up your method in a Runnable and execute it yourself.

Corin Fletcher
  • 1,611
  • 1
  • 17
  • 25
4

This is a complementary answer to the accepted one. You can call an async method in your own class, but you have to create a self-referential bean.

The only side-effect here is that you cannot call any async code inside the constructor. It is a nice way to keep your code all in the same place.

@Autowired ApplicationContext appContext;
private MyAutowiredService self;

@PostConstruct
private void init() {
    self = appContext.getBean(MyAutowiredService.class);
}

public void doService() {
    //This will invoke the async proxy code
    self.doAsync();
}

@Async 
public void doAsync() {
    //Async logic here...
}
Kirk Backus
  • 4,776
  • 4
  • 32
  • 52
3

I had a problem similar to this. And I spent a lot of time to fix it.

If you use spring-context 3.2, you also need to add @EnableAsync on the class where you call the method service annotated @Async

Take a look at http://spring.io/guides/gs/async-method/#initial

I hope that it'll help you.

Salim Hamidi
  • 20,731
  • 1
  • 26
  • 31
0

You can use @EnableAsync in your service...

Alireza Alallah
  • 2,486
  • 29
  • 35