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生产者的包装类,然后做一层消息数据(待发送数据)的缓存,然后发布的时候从缓存取数据。

浙公网安备 33010602011771号