JDK9 Flow订阅发布简单demo 结合Spring容器

直接列代码应该都能看懂,用了lombok的log注解@Slf4j

@Configuration
@Slf4j
public class MessageQueueConfig implements CommandLineRunner {

    @Bean
    @Qualifier("producer")
    @Primary
    public SubmissionPublisher<Object> producer(){
        SubmissionPublisher<Object> submissionPublisher = new SubmissionPublisher<>();
        log.info("生产者创建成功");
        log.info("生产者发送了一条信息 xxx00");
        submissionPublisher.submit("xxx00");
        return submissionPublisher;
    }

    @Override
    public void run(String... args) throws Exception {
        List<String> list = List.of("a","b","c","d");
        list.forEach(i->{
            log.info("生产者发送了一条信息 "+i);
            producer().submit(i);
        });
    }
}
@Component
@Slf4j
public class MessageUtil implements ApplicationContextAware, ApplicationRunner {

    private static ApplicationContext context;


    public static void subscribe(Flow.Subscriber subscriber){
        context.getBean(SubmissionPublisher.class).subscribe(subscriber);
    }

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

    @Override
    public void run(ApplicationArguments args) throws Exception {
        MessageUtil.subscribe(new Consumer("消费者2"));
    }


    public static class Consumer<T> implements Flow.Subscriber<T>{

        private Flow.Subscription subscription;

        private String subId;

        public volatile Boolean isComplete = false;

        public Consumer(String subId) {
            this.subId = subId;
            log.info("消费者创建成功");
        }

        @Override
        public void onSubscribe(Flow.Subscription subscription) {
            this.subscription = subscription;
            log.info(subId+"-订阅成功");
            subscription.request(1);
        }

        @Override
        public void onNext(T item) {
            log.info(subId+"接收到数据 "+ item);
            subscription.request(1);
        }

        @Override
        public void onError(Throwable throwable) {
            throwable.printStackTrace();
        }

        @Override
        public void onComplete() {
            log.info(subId+" 订阅结束");
            isComplete = true;
        }
    }
}

测试可以发现消费者并不能消费在订阅前发布的消息,针对这个可以写一个SubmissionPublisher生产者的包装类,然后做一层消息数据(待发送数据)的缓存,然后发布的时候从缓存取数据。

posted @ 2023-05-17 17:06  DreamCatt  阅读(24)  评论(0)    收藏  举报