How to get spring-boot @Async to work with Java 8

Marci-man :

I am trying to call a method asynchronously. But somehow it doesn't work. Could someone please help me resolve this issue?

My main entry point:

@SpringBootApplication
@EnableAsync
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
        AsyncService asyncService = new AsyncService();
        asyncService.asyncMethod();
        asyncService.asyncMethod();
    }

}

Async Service:

@Component
public class AsyncService {

    @Async
    public void asyncMethod(){

        log.info("starting...");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("ending...");
    }
}

And finally, in log I am expecting:

  1. starting...
  2. starting...
  3. ending...
  4. ending...

but this is what I get:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-02-13 17:52:41.548  INFO 85734 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication on mntbden00122972 with PID 85734 (/Users/h3560/demo/target/classes started by h3560 in /Users/h3560/demo)
2019-02-13 17:52:41.550  INFO 85734 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2019-02-13 17:52:42.084  INFO 85734 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 0.76 seconds (JVM running for 1.329)
2019-02-13 17:52:42.086  INFO 85734 --- [           main] com.example.demo.services.AsyncService   : starting...
2019-02-13 17:52:44.088  INFO 85734 --- [           main] com.example.demo.services.AsyncService   : ending...
2019-02-13 17:52:44.089  INFO 85734 --- [           main] com.example.demo.services.AsyncService   : starting...
2019-02-13 17:52:46.091  INFO 85734 --- [           main] com.example.demo.services.AsyncService   : ending...
Andronicus :

@Async is spring's annotation that is being applied to public methods on proxies (that's why they need to be public). Self invocation does not work.

In your example, you are not using dependency injection mechanism from spring, so no proxy is being created. To bypass it, you need to make a @Bean out of it (which you have done by annotating it with @Component) and @Autowire it before execution:

@SpringBootApplication
@EnableAsync
public class DemoApplication {

@Autowired
AsyncService asyncService;

    public someMethod() {
        SpringApplication.run(DemoApplication.class, args);
        asyncService.asyncMethod();
        asyncService.asyncMethod();
    }

}

With this spring AOP can wrap the component into proxy and execute the method asynchronously.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=111299&siteId=1