2

In my software I use @Async to call a certain method from a Bean in the background, on Tomcat startup, and this works as expected.

But, under some defined circumstances, what the method does is failing, and the method myUtil.connect() calls itself then to try again.

The basic code looks as follows.

The bean definition:

import org.springframework.context.annotation.Bean;
import package.MyService;

@Bean(initMethod = "init", destroyMethod = "destroy")
MyService myService() {
    MyService bean = new MyService();
    return bean;
}

And the MyService bean:

import javax.inject.Inject;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class MyService {

    @Inject
    private MyUtil         myUtil;

    @Async
    public void init() {
        myUtil.connect();
    }
}

I have tried annotating the method connect() also with @Async believing, since it calls itself, @Async would make it run in background as well, with no success.

Is there a way to assure subsequent calls to connect() "remain" in the background ?

Edit:

Would it be working to make connect() a wrapper around a function which does the real work? This way connect() would just be called once, and the wrapped function would call itself in case of failure.

3
  • Which method calls itself? And where and what calls init()? Commented Mar 17, 2014 at 21:05
  • 5
    @ASync is probably using a proxy and internal call are not proxied. Commented Mar 17, 2014 at 21:22
  • Does connect() call itself? What do you expect to happen? What actually happens? Commented Mar 17, 2014 at 23:04

1 Answer 1

2

The working solution for my requirement goes like this:

First I had to add @EnableAsync to my root context configuration class (which is the configuration class that creates the MyService bean).

Then I moved the @Async annotation from the MyService to the MyUtils class.

MyService class:

import javax.inject.Inject;
import org.springframework.stereotype.Component;

@Component
public class MyService {

    @Inject
    private MyUtil         myUtil;


    public void init() {
        myUtil.connect();
    }
}

MyUtil class:

@Component
public class MyUtil {

    @Async
    public void connect() {}

}

The documentation at http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-annotation-support-async gave the necessary hint:

To asynchonously initialize Spring beans you currently have to use a separate initializing Spring bean that invokes the @Async annotated method on the target then.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.