美文网首页
SpringBoot的ApplicationEvent和List

SpringBoot的ApplicationEvent和List

作者: King斌 | 来源:发表于2021-04-15 08:26 被阅读0次

    ApplicationEvent和Listener是Spring提供的一个事件发布与监听机制,底层采用的观察者模式实现,可以很方便的实现业务逻辑的解耦,提高程序的可扩展性和阅读性。

    一、自定义发布事件
    1、自定义类继承ApplicationEvent类,重载构造函数

    /**
     * 业务日志发布事件
     *
     * @Author YUBIN
     * @create 2019-06-15
     */
    @Getter
    public class BusinessLogEvent extends ApplicationEvent {
        private BusinessLogDto businessLogDto;
    
        public BusinessLogEvent(Object source, BusinessLogDto businessLogDto) {
            super(source);
            this.businessLogDto = businessLogDto;
        }
    }
    

    2、dto类的书写

    /**
     * 业务处理日志dto类
     *
     * @Author YUBIN
     * @create 2019-06-15
     */
    @Getter
    @Setter
    public class BusinessLogDto {
        // 业务类型
        private String type;
        // 业务处理时长
        private long businessTime;
        // 业务处理结果
        private String result;
        // 请求参数
        private String params;
    }
    3、书写相关业务类发布事件
    发布事件采用的是applicationContext.pushEvent(....)
    
    @Service
    public class OrderServiceImpl implements OrderService {
    
        @Autowired
        private ApplicationContext applicationContext;
    
        @Override
        public BaseResponse pushOrder(Order order) {
            BaseResponse response = new BaseResponse();
            response.setCode(1);
            response.setMessage("SUCCESS");
            // 业务处理相关 ....
    
            BusinessLogDto dto = new BusinessLogDto(BusinessType.PUSH_ORDER.getType(), JSON.toJSONString(response), JSON.toJSONString(order));
            applicationContext.publishEvent(new BusinessLogEvent(this, dto));
            return response;
        }
    }
    

    二、注册监听
    1、使用实现ApplicationListener接口的形式注册监听

    /**
     * 注册业务处理日志事件监听器
     *
     * @Author YUBIN
     * @create 2019-06-15
     */
    @Component // 将此类交给spring管理,就无需在手动的在SpringApplication中去注册了
    @Slf4j
    public class RegisterListener implements ApplicationListener<BusinessLogEvent> {
        @Override
        public void onApplicationEvent(BusinessLogEvent businessLogEvent) {
            BusinessLogDto businessLogDto = businessLogEvent.getBusinessLogDto();
            log.info(String.format("RegisterListener 接收到的监听数据是: %s", JSON.toJSONString(businessLogDto)));
        }
    }
    

    使用实现ApplicationListener接口的形式,在注册监听器的时候,除了在该类上加上@Component注解交给sPRING管理之外,还可以通过SpringApplication.addListeners(...) 或SpringApplicationBuilder.listeners(...)方法注册它们。也可以通过将META-INF / spring.factories文件添加到项目中,并使用org.springframework.context.ApplicationListener引用你的监听器。 org.springframework.context.ApplicationListener=com.yubin.springboot.listener.RegisterListener

    2、使用注解@EventListener实现监听

    /**
     * 使用注解的形式注解监听器
     *
     * @Author YUBIN
     * @create 2019-06-15
     */
    @Component
    @Slf4j
    public class AnnotationRegisterListener {
    
        /**
         * 注册监听实现方法
         * @param businessLogEvent 业务处理推送事件
         */
        @EventListener
        public void register(BusinessLogEvent businessLogEvent) {
            // 获取业务处理日志对象
            BusinessLogDto businessLogDto = businessLogEvent.getBusinessLogDto();
    
            //../省略逻辑
    
            //输出业务处理日志信息
            log.info(String.format("AnnotationRegisterListener 接收到的监听数据是: %s", JSON.toJSONString(businessLogDto)));
        }
    }
    

    如果在你的项目中存在多个监听器,你想按照你的设想去定义监听器的执行顺序,可以通过在类上增加@Order注解来定义

    三、使用@Async实现异步监听
    @Aysnc其实是Spring内的一个组件,可以完成对类内单个或者多个方法实现异步调用,这样可以大大的节省等待耗时。内部实现机制是线程池任务ThreadPoolTaskExecutor,通过线程池来对配置@Async的方法或者类做出执行动作。

    1、书写异步线程池配置类

    /**
     * 监听器异步线程池配置类
     *
     * @Author YUBIN
     * @create 2019-06-16
     */
    @Configuration
    @EnableAsync
    public class ListenerAsyncConfiguration implements AsyncConfigurer {
    
        /**
         * 获取异步线程池执行对象
         * @return
         */
        @Override
        public Executor getAsyncExecutor() {
            //使用Spring内置线程池任务对象
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            //设置线程池参数
            taskExecutor.setCorePoolSize(5);
            taskExecutor.setMaxPoolSize(10);
            taskExecutor.setQueueCapacity(25);
            taskExecutor.initialize();
            return taskExecutor;
        }
    
        @Override
        public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
            return null;
        }
    }
    

    2、在需要的方法上加上@Async注解

    @Component  // 将此类交给spring管理,就无需在手动的在SpringApplication中去注册了
    @Slf4j
    @Order(0)
    public class RegisterListener implements ApplicationListener<BusinessLogEvent> {
    
        @Override
        @Async
        public void onApplicationEvent(BusinessLogEvent businessLogEvent) {
            try {
                Thread.sleep(10000); // 使当前线程休眠10s
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            BusinessLogDto businessLogDto = businessLogEvent.getBusinessLogDto();
            log.info(String.format("RegisterListener 接收到的监听数据是: %s", JSON.toJSONString(businessLogDto)));
        }
    }
    

    相关文章

      网友评论

          本文标题:SpringBoot的ApplicationEvent和List

          本文链接:https://www.haomeiwen.com/subject/jpaqlltx.html