欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

EventBus监听模式实例

程序员文章站 2024-01-20 16:51:40
...

目录

先定义一个注解

自定义一个EventBus

EventBus启动配置

定义事件类型实体, 和对应的监听操作

发布事件

小结


先定义一个注解

/**
 * eventbus开启注解,只有开启了该注解的类的方法才可用Subscribe注解监听event事件
 * @author zsd
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Component
public @interface EventHandler {

}

自定义一个EventBus

@Slf4j
public class EventBus implements InitializingBean {

    private org.greenrobot.eventbus.EventBus publisher;

    private TransactionTemplate transactionTemplate;

    private PlatformTransactionManager platformTransactionManager;

    public EventBus(org.greenrobot.eventbus.EventBus publisher, PlatformTransactionManager platformTransactionManager) {
        this.platformTransactionManager = platformTransactionManager;
        this.publisher = publisher;
    }

    public void register(Object bean) {
        publisher.register(bean);
    }

    public void unregister(Object bean){
        publisher.unregister(bean);
    }

    public void publishAfterTransaction(Serializable message) {
        if (TransactionSynchronizationManager.isSynchronizationActive()
                && transactionTemplate != null) {
            TransactionSynchronizationManager.registerSynchronization(
                    new TransactionSynchronizationAdapter() {
                        @Override
                        public void afterCompletion(int status) {
                            if (status == TransactionSynchronization.STATUS_COMMITTED) {
                                transactionTemplate.execute(
                                        status1 -> {
                                            EventBus.this.publish(message);
                                            return null;
                                        });
                            }
                        }
                    });
        } else {
            EventBus.this.publish(message);
        }
    }

    public void publish(Serializable message) {
        if(log.isDebugEnabled()) {
            log.debug("发送事件:{}", message);
        }
        publisher.post(message);
    }


    @Override
    public void afterPropertiesSet(){
        if (platformTransactionManager != null) {
            DefaultTransactionDefinition defaultTransactionDefinition =
                    new DefaultTransactionDefinition();
            defaultTransactionDefinition.setPropagationBehavior(
                    TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            transactionTemplate =
                    new TransactionTemplate(platformTransactionManager, defaultTransactionDefinition);
        } else {
            log.warn("spring事务管理器不存在,publishAfterTransactionCommitted方法不会绑定到事务中!");
        }
    }

}

EventBus启动配置

@Configuration
@Setter
@Slf4j
public class EventBusAutoConfiguration implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Resource
    private ExecutorService executorService;

    @Autowired(required = false)
    private PlatformTransactionManager platformTransactionManager;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Bean
    public EventBus eventBus(){
        EventBusBuilder eventBusBuilder = org.greenrobot.eventbus.EventBus.builder().executorService(executorService);
        org.greenrobot.eventbus.EventBus eBus = eventBusBuilder.build();
        EventBus eventBus = new EventBus(eBus, platformTransactionManager);
        eventBus.afterPropertiesSet();
        return eventBus;
    }


    @Configuration
    @AutoConfigureAfter(EventBusAutoConfiguration.class)
    public static class EventHandlerConfig {
        @Autowired
        private EventBus eventBus;

        @PostConstruct
        public void afterPropertiesSet(){
            Map<String, Object> beansWithAnnotation =
                    SpringApplicationContextHolder.getApplicationContext().getBeansWithAnnotation(EventHandler.class);
            for (Object o : beansWithAnnotation.values()) {
                eventBus.register(o);
                log.info("注册事件处理器:{}", o.getClass().getName());
            }
        }

        @PreDestroy
        public void destroy(){
            Map<String, Object> beansWithAnnotation =
                    SpringApplicationContextHolder.getApplicationContext().getBeansWithAnnotation(EventHandler.class);
            for (Object o : beansWithAnnotation.values()) {
                eventBus.unregister(o);
                log.info("销毁事件处理器:{}", o.getClass().getName());
            }
        }
    }
}

接下来是如何使用

定义事件类型实体, 和对应的监听操作

@EventHandler
@Slf4j
public class OrderEventListener {

    @Subscribe
    public void onOrderCreate(OrderCreateEvent event) {
        log.info("onOrderCreate : {}", event);
    }

    @Subscribe
    public void onOrderUpdate(OrderUpdateEvent event) {
        log.info("onOrderUpdate : {}", event);
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onOrderDelete(OrderDeleteEvent event) {
        log.info("onOrderDelete : {}", event);
    }

    @Getter
    @AllArgsConstructor
    public static class OrderCreateEvent implements Serializable {

        private static final long serialVersionUID = -7018526633366219070L;

        public String name;

    }

    @Getter
    @AllArgsConstructor
    public static class OrderDeleteEvent implements Serializable {

        private static final long serialVersionUID = -1514539831268656303L;

    }

    @Getter
    @AllArgsConstructor
    public static class OrderUpdateEvent implements Serializable {

        private static final long serialVersionUID = 3668604429118137965L;

    }

}

发布事件

@Service
public class MyService {
    @Autowired
    private EventBus eventBus;

    public void getNames(){
        OrderEventListener.OrderCreateEvent event = new OrderEventListener.OrderCreateEvent("zsd");
        eventBus.publish(event);
    }
}

小结

一种内存中的发布订阅模式,或者监听器模式, 重在解耦

 

相关标签: 百宝箱