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

  1. Enable the @enableAsync asynchronous event

  2. 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
  1. 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
  1. 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