Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use @Async correctly in Spring

I have a question about Spring's @Async annotation and how to correctly use it. Let's say I have these methods:

@Async
public void test(String param1) {
    test2(param1, null);
}

@Async
public void test2(String param1, String param2) {
    test3(param1, param2, null);
}

@Async
public void test3(String param1, String param2, String param3) {
    // do some heavy work
}

Do I need to have @Async on all three methods for it to be called asynchronously or is it enough only to have it on test3 that will actually do the work?

like image 288
Vedran Kopanja Avatar asked Nov 30 '15 08:11

Vedran Kopanja


1 Answers

You do need it only at one method. Just because, after a new thread is started with the first @Async-method, is is asynchronous to the invoking method.

But what this mean for you, is highly depending on what your example should illustrate:

1) So in your case, an @Async for test1(String param1) is enough when you ever invoke test2 and test3 through test1.

@Async
public void test1(String param1) {
    test2(param1, null);
}

private void test2(String param1, String param2) {
    test3(param1, param2, null);
}

private void test3(String param1, String param2, String param3) {
    // do something
}

note that the methods 2 and 3 are private


2) But if your example is for illustrating a method overloading pattern for default parameters (Method chaining), then it is more complicate. Then you would need to have the @Async annotation at the method that do the real stuff. Because you just want to execute the real execution in an async-way, but not one async invocation for each chaining step.

public void test(String param1) {
    test(param1, null);
}


public void test(String param1, String param2) {
    //this invocation runs async only when real AspectJ is used
    test(param1, param2, null);
}

@Async
public void test(String param1, String param2, String param3) {
    // do something
}

note that all methods are named just test (method chaining pattern)

The problem with this is, that Spring (without real AspectJ load- or compile-time weaving) will not run a method async if it is invoked via this! (see https://stackoverflow.com/a/22561903/280244)

like image 194
Ralph Avatar answered Oct 18 '22 09:10

Ralph