2

I've an spring component which has some methods as @Async.

I want to create a private method and run @Async but it won't works because spring doesn't help self invocation from withing the bean...

Is there a simple way to allow a specific private method to allos AOP @Async? or is just simpler to get a threadpool and execute manually?

2 Answers 2

3

instead of calling your async method on this, inject the bean and call the method on the bean. here is a example:

public class MyService {
    
    @Lazy
    @Autowired
    private MyService myService;
    
    public void doStuff() throws Exception {
        myService.doStuffAsync();
        System.out.println("doing stuff sync.");
    }
    
    @Async
    public void doStuffAsync() throws Exception {
        TimeUnit.SECONDS.sleep(3);
        System.out.println("doing stuff async.");
    }
}
  • you have to use @Lazy!
  • you have to call myService.doStuffAsync() instead of this.doStuffAsync()
Sign up to request clarification or add additional context in comments.

5 Comments

it will work i assume but this looks so ugly
i agree, but you need to provide more information about your problem.
Do note that this answer does not cover the main requirement of the question - allow a specific private method. Spring AOP cannot advise private methods .
as i understand OP wants to call a async public method from a private method, which will work fine.
Rafael, if you find it so ugly, switch to native AspectJ. No more proxies, easy to intercept self-invocation. You cannot have the full power of AspectJ in Spring's own "AOP lite" framework and have to make a choice. But AspectJ also works fine in Spring, just in a somewhat different way with regard to configuration and handling.
0

You can submit the task to a ThreadPoolTaskExecutor directly.

This is more flexible than injecting the proxy bean into the class itself, as @Yevgeniy suggest. In my opinion, its less confusing to someone looking at your code.

It also avoids the whole issue with the class getting proxied, which can mean you need to use @Getter/@Setter's on the async class methods.

In my experience, there have been too many quirks to @Async to make it worth it, and the actual amount of typing you're saving is minimal.

Example:

var future = executor.submit(() -> myAsyncMethod())

1 Comment

it doesn't satisfy the question's requirements – the OP wants to use @Async and a private method

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.