scenario
In some service scenarios, asynchronous events are required to decouple services and improve response speed, for example, sending short messages and synchronizing information after users are registered. These scenarios can be solved using MQ, but is there a lighter solution? Yes, Spring’s built-in event listener can be implemented in conjunction with asynchronous methods
Demo
-
Enable the @enableAsync asynchronous event
-
Create an event, and the object to receive can be customized. Here, use String to demonstrate
public class SysLogEvent extends ApplicationEvent {
/ * * *@param source
*/
public SysLogEvent(String source) {
super(source); }}Copy the code
- The listener
@Slf4j
@Component
public class SysLogListener {
@Async
@EventListener(SysLogEvent.class)
public void saveSysLog(SysLogEvent event) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("[Receive event] {} {}", event.getSource(), event.getTimestamp()); }}Copy the code
- Sending listening Events
@RestController
@Slf4j
public class DemoController {
@Resource
private ApplicationContext ctx;
@GetMapping("/test")
public void test(a) {
log.info("[Send event]");
ctx.publishEvent(new SysLogEvent("Ha ha")); }}Copy the code
The completion of
Asynchronous thread pool configuration
@async Essentially uses thread pool for processing tasks. In actual development, thread pool size needs to be configured according to business scenarios
/ * * *@author HeyS1
* @description* /
@Slf4j
@Configuration
@EnableAsync
public class SchedulingConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor(a) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// The core thread
executor.setCorePoolSize(2);
// Maximum thread
executor.setMaxPoolSize(20);
// Queue size
executor.setQueueCapacity(5);
// If the thread pool size is larger than the coreSize, the maximum waiting time for the redundant threads will be destroyed
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("taskExecutor-");
// How to handle new tasks when the pool size reaches its Max size
//@see <a href="https://blog.csdn.net/foreverling/article/details/78073105"></a>
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
executor.initialize();
return executor;
}
/** * Exception handling in asynchronous tasks */
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler(a) {
return (ex, method, params) -> {
log.error("= = = = = = = = = = = = = = = = = = = = = = = = = =" + ex.getMessage() + "= = = = = = = = = = = = = = = = = = = = = = =", ex);
log.error("exception method:"+ method.getName()); }; }}Copy the code