EventBus 同步与异步使用

124 阅读2分钟

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>33.0.0-jre</version>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

`


/**
 * 订单
 */
public class Order {
}

`

/**
 * 事件的基础类型
 */
public class EventBean<T> implements Serializable {

    private T data;
    public EventBean(T data){
        this.data=data;
    }

}

`


import lombok.Data;

@Data
//@ConfigurationProperties(prefix = "eventbus.pool")
public class EventBusExecutorProperites {
    /**
     * 核心线程数
     */
    private int corePoolSize = 5;
    /**
     * 最大线程数
     */
    private int maxPoolSize = 20;
    /**
     * 空闲线程销毁时间
     */
    private int keepAliveSeconds = 60;

    /**
     * 任务队列容量
     */
    private int queueCapacity = 1000;

    /**
     * 是否允许核心线程空闲退出
     */
    private boolean allowCoreThreadTimeOut = false;

    /**
     * 线程前缀
     */
    private String threadNamePrefix = "event-bus-pool-";
}

`


@Slf4j
@Configuration
//@EnableConfigurationProperties(EventBusExecutorProperites.class)
public class EventBusConfiguration implements ApplicationListener<ContextRefreshedEvent> {


    private EventBusExecutorProperites executorProperites=new EventBusExecutorProperites();

    @Bean("eventBusExecutor")
    @Primary
    public Executor getThreadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程
        executor.setCorePoolSize(executorProperites.getCorePoolSize());
        // 最大线程数
        executor.setMaxPoolSize(executorProperites.getMaxPoolSize());
        // 任务队列容量
        executor.setQueueCapacity(executorProperites.getQueueCapacity());
        // 线程前缀
        executor.setThreadNamePrefix(executorProperites.getThreadNamePrefix());
        // 是否允许核心线程空闲退出
        executor.setAllowCoreThreadTimeOut(executorProperites.isAllowCoreThreadTimeOut());
        // 空闲线程销毁时间
        executor.setKeepAliveSeconds(executorProperites.getKeepAliveSeconds());
        // 任务装饰器-增强器,类似于aop
        executor.setTaskDecorator(new MDCTaskDecorator());
        // 不丢弃任务 由调用线程处理该任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 如果为true 线程池shutdown false 为 shutdownNow
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.initialize();
        return executor;
    }

    static class MDCTaskDecorator implements TaskDecorator {
        @Override
        public Runnable decorate(Runnable runnable) {
            // 获取当前线程的MDC上下文数据副本,并存储在 mdcContext 中。
            Map<String, String> contextMap = MDC.getCopyOfContextMap();
            return () -> {
                if (contextMap != null) {
                    // 将 mdcContext 中的数据重新设置回当前线程的MDC,以恢复或传递上下文数据给其他线程或任务。
                    MDC.setContextMap(contextMap);
                }
                runnable.run();
            };
        }
    }

    @Bean("asyncEventBus")
    public AsyncEventBus asyncEventBus() {
        return new AsyncEventBus(getThreadPoolTaskExecutor());
    }

    @Bean("eventBus")
    public EventBus eventBus() {
        return new EventBus();
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        registerSubscribes(event.getApplicationContext());
    }

    private void registerSubscribes(ApplicationContext context) {
        if (null == context) {
            return;
        }
        // 根据上下文获取类型为 BaseCallable 的bean
        String[] beanDefinitionNames = context.getBeanNamesForType(SyncEvents.class, false, true);
        // 根据上下文获取eventbus的bean,用于注册
        EventBus eventBus = context.getBean("eventBus",EventBus.class);
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = context.getBean(beanDefinitionName);
//            try {
//                Class<?> aClass = bean.getClass();
//                Method call = aClass.getMethod("call", BaseCallableBean.class);
//                if (null == call) {
//                    continue;
//                }
//                log.info("EventBus method-Subscribe register bean[{}]", beanDefinitionName);
//            } catch (NoSuchMethodException e) {
//                log.info("EventBus method-Subscribe register bean Exception : {}", e.getMessage());
//                e.printStackTrace();
//            }
            eventBus.register(bean);
            System.out.println("eventBus \t"+beanDefinitionName);
        }

            String[] aybeanDefinitionNames = context.getBeanNamesForType(AsyncEvents.class, false, true);
            // 根据上下文获取eventbus的bean,用于注册
            AsyncEventBus asyncEventBus = context.getBean("asyncEventBus",AsyncEventBus.class);
            for (String aybeanDefinitionName : aybeanDefinitionNames) {
                Object aybean = context.getBean(aybeanDefinitionName);
//            try {
//                Class<?> aClass = bean.getClass();
//                Method call = aClass.getMethod("call", BaseCallableBean.class);
//                if (null == call) {
//                    continue;
//                }
//                log.info("EventBus method-Subscribe register bean[{}]", beanDefinitionName);
//            } catch (NoSuchMethodException e) {
//                log.info("EventBus method-Subscribe register bean Exception : {}", e.getMessage());
//                e.printStackTrace();
//            }
                asyncEventBus.register(aybean);
                System.out.println("asyncEventBus \t"+aybeanDefinitionName);
        }
    }
}
/**
 * 同步
 */
public interface SyncEvents {

}
/**
 * 异步集成
 */
public interface AsyncEvents {
}
@Component
public class GoodsEvent implements OrderEventBus, AsyncEvents {
    @Override
    public void placeOrderEvent(EventBean<Order> event) {
        System.out.println("GoodsEvent:商品快照事件");
    }
}

`

@Component
public class NoticeEvent implements OrderEventBus, AsyncEvents {
    @Override
    public void placeOrderEvent(EventBean<Order> event) {
        System.out.println("NoticeEvent:通知事件");
    }
}

`

`

@Component
public class OrderEvent implements OrderEventBus, AsyncEvents {
    @Override
    public void placeOrderEvent(EventBean<Order> event) {
        System.out.println("OrderEvent:订单下单事件");
    }
}

`

`


@Component
public class WeCharPayEvent implements OrderEventBus, SyncEvents {
    @Override
    public void placeOrderEvent(EventBean<Order> event) {
        System.out.println("OrderEvent:微信支付获取支付参数");
    }
}

`

`

@Slf4j
@RestController
@RequestMapping
public class TestController {

    @Resource
    private AsyncEventBus asyncEventBus;

    @Resource
    private EventBus eventBus;


    @GetMapping
    public void guavaPost(){
        Order order=new Order();
        EventBean<Order> eventBean=new EventBean<Order>(order);


        System.out.println("看看谁我在后面执行呢");
        eventBus.post(eventBean);
        System.out.println("看看我在谁前面执行呢");
        asyncEventBus.post(eventBean);

    }

}

`