Spring call to @Async method inside @Scheduled method

I am using Spring boot with @EnableScheduling and @EnableAsync .

I have a method that annotates using @Scheduled . I have some more methods that are annotated using @Async .

Now I call these @Async methods in the @Async method and print the name of the current stream in async methods. I see that they all have the same stream name, in fact it is a stream that uses the @Scheduled method.

I do not see the execution of the asynchronous method. What is wrong here?

Here is my application boot class

 @SpringBootApplication @EnableScheduling @EnableAsync public class ApplicationBoot { public static void main(String[] args) { SpringApplication.run(ApplicationBoot.class, args); } } 

Here is my planner class

 @Component public class TaskScheduler { private static final Logger logger = Logger.getLogger(TaskScheduler.class); @Scheduled(fixedDelay = 10000) public void ScheduledMethod() { methodOne(); methodTwo(); methodThree(); } @Async private void methodOne() { logger.info("Method one called by Thread : " + Thread.currentThread().getName() + " at " + new Date()); } @Async private void methodTwo() { logger.info("Method two called by Thread : " + Thread.currentThread().getName() + " at " + new Date()); } @Async private void methodThree() { logger.info("Method three called by Thread : " + Thread.currentThread().getName() + " at " + new Date()); } } 

Output

Method one, called by thread: pool-1-thread-1 on Tue Apr 04 16:32:27 IST 2017

Method two is called thread: pool-1-thread-1 in Tue Apr 04 16:32:27 IST 2017

Method three is called thread: pool-1-thread-1 in Tue Apr 04 16:32:27 IST 2017

+5
source share
2 answers

Explanation

Spring creates a proxy server around your instance. ScheduledMethod internally calls 3 methods that are not proxied and therefore not asynchronous.

cf. documentation :

If you call a method on an object reference, the method is called directly on that object reference, as shown below.

See this question. Spring AOP does not work when the method is called inside the bean for a workaround, but the best one is suggested in the document The best approach (the term best is used loosely here) is to refactor your code such that the self-invocation does not happen...

Note that the private method is not supported:

Due to the proxy server-based Spring s AOP framework, secure methods are by definition not intercepted for either the JDK proxy (where this is not applicable) or the CGLIB proxy (where it is technically possible but not recommended for AOP purposes). As a result, any given pointcut will be matched with public methods only!

Workaround Example

 @Component public class ServiceMethod { private static final Logger logger = Logger.getLogger(ServiceMethod .class); @Async public void methodOne() { logger.info("Method one called by Thread : " + Thread.currentThread().getName() + " at " + new Date()); } @Async public void methodTwo() { logger.info("Method two called by Thread : " + Thread.currentThread().getName() + " at " + new Date()); } @Async public void methodThree() { logger.info("Method three called by Thread : " + Thread.currentThread().getName() + " at " + new Date()); } } @Component public class TaskScheduler { private static final Logger logger = Logger.getLogger(TaskScheduler.class); @Autowired private ServiceMethod serviceMethod; @Scheduled(fixedDelay = 10000) public void ScheduledMethod() { serviceMethod.methodOne(); serviceMethod.methodTwo(); serviceMethod.methodThree(); } } 
+8
source

You may not have configured Thread Pool with more Threads for Scheduler .

From docs

If you did not specify a pool size attribute, the default thread pool will have only one thread.

+3
source

Source: https://habr.com/ru/post/1266299/


All Articles