1つは、SmartApplicationListenerの紹介です
Spring ApplicationEventと対応するリスナーは、イベントモニタリング、パブリッシュ、サブスクライブの実装を提供します。内部実装はオブザーバーモードであり、ビジネスシステム間でビジネスを分離し、システムのスケーラビリティ、再利用性、および保守性を提供できます。
Springが提供するApplicationEvent&Listenerは、次の3つの方法で実装できます。
- @EventListenerアノテーションメソッド;
- ApplicationListenerインターフェースを実装します。
- SmartApplicationListenerインターフェースを実装します。
この記事では、SmartApplicationListenerの使用方法を紹介します。
SmartApplicationListenerインターフェイスは、ApplicationListenerインターフェイスとOrderedインターフェイスを継承し、イベントの監視と並べ替えの機能を実装します。
SmartApplicationListenerには、次の2つのメソッドがあります。
/**
* 指定支持哪些类型的事件
*/
boolean supportsEventType(Class<? extends ApplicationEvent> var1);
/**
* 指定支持发生事件所在的类型
*/
boolean supportsSourceType(Class<?> var1);
2、SmartApplicationListenerコードの実装
SmartApplicationListenerは、高度なリスナーであり、ApplicationListenerのサブクラスであり、整然とした監視を実現できます。
この記事のコード:https://github.com/nomico271/inspire-demo/tree/master/Ch2_SmartApplicationListener
1.SmartApplicationListenerの使用例
注文が作成された後、さらに処理するために注文作成メッセージをKafkaクラスターに送信する必要があるとすると、前の擬似コードは次のようになります。
public void createOrder(long spuId) {
// 创建订单
long orderId = processCreateOrder(spuId);
// 订单创建成功
if (orderId > 0) {
// 发送kafka消息
sendKafkaMsg(orderId);
}
}
すべてのプロセスが結合されています(もちろん、この記事は単なる例であり、いくつかのステップを結合する必要があります)。
では、SmartApplicationListenerを使用してこれらのステップを分離する方法は?
(1)まず、送信する必要のある基本情報を含むイベントソースオブジェクトを定義します。
public class OrderDTO {
private long orderId;
private String spuId;
private int orderStatus;
private Date createTime;
private Date updateTime;
}
(2)何が起こったかを定義します。
@Getter
public class OrderStatusMsgEvent extends ApplicationEvent {
private OrderDTO orderDTO;
/**
* 重写构造函数
*
* @param source 发生事件的对象
* @param orderDTO 注册用户对象
*/
public OrderStatusMsgEvent(Object source, OrderDTO orderDTO) {
super(source);
this.orderDTO = orderDTO;
}
}
(3)イベントリリース
// 抽象事件发布
public interface EventPublishService<T> {
void publishEvent(T event);
}
// Spring 实现的事件发布组件
@Component("springEventPublishService")
public class SpringEventPublishService implements EventPublishService<ApplicationEvent>, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void publishEvent(ApplicationEvent event) {
applicationContext.publishEvent(event);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
(4)イベント監視:イベントが発生すると、イベントの変更通知が監視され、さらに処理されます。
@Component
public class OrderEventListener implements SmartApplicationListener {
/**
* 支持的事件类型
*
* @param eventType
* @return
*/
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return eventType == OrderStatusMsgEvent.class;
}
/**
* 事件发生的目标类
*
* @param sourceType 事件发生的目标类类型
* @return
*/
@Override
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return true;
}
@Override
public int getOrder() {
return 0;
}
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
// 获取注册用户信息
OrderStatusMsgEvent orderStatusMsgEvent = (OrderStatusMsgEvent) applicationEvent;
OrderDTO orderInfo = orderStatusMsgEvent.getOrderDTO();
// 模拟kafka发送
// kafkaProducer.sendMsg(orderInfo);
System.out.println("======kafka发送成功====");
}
}
(5)変革:Springイベント公開メカニズムを使用してビジネスの分離を実現する方法
元の擬似コードでは、上記の方法が変換に使用されます。コードは次のとおりです。
@Autowired
@Qualifier("springEventPublishService")
private EventPublishService publishService;
public void createOrder(long spuId) {
// 创建订单
long orderId = processCreateOrder(spuId);
// 订单创建成功
if (orderId > 0) {
// 利用事件发布机制实现创建订单与发送Kafka消息业务的解耦
OrderDTO orderDTO = buildOrderInfo(orderId);
publishService.publishEvent(new OrderStatusMsgEvent(this, orderDTO));
}
}
上記のSpringSmartApplicationListenerによって実装されたイベント駆動型モデルにより、Kafkaメッセージ送信をメインの注文プロセスビジネスから切り離すことができます。もちろん、上記は単なる例であり、Springのイベント公開メカニズムを適用する単純さを反映していません。このデモは、Spring SmartApplicationListenerの使用法を紹介するためのものです。実際のアプリケーションでは、このメソッドを使用したビジネスデカップリングにより適したシナリオが存在する場合があります。たとえば、注文ステータスが変更された場合、この記事で紹介したメソッドを使用してメッセージを送ります。
2.SmartApplicationListenerは非同期の使用例をサポートします
SmartApplicationListenerによって実装されたSpringイベント駆動型モデルを、Springによって提供された@Async
アノテーションと組み合わせて使用して、非同期呼び出しを実装できます。@Async
実現は、構成されたスレッドプールタスクThreadPoolTaskExecutorを使用して、アノテーションが配置されているメソッドを実行することです。
(1)スプリング構成方法(パラメーター自己構成):
<!-- 开启@AspectJ AOP代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 任务执行器 -->
<task:executor id="asyncExecutor" pool-size="10" queue-capacity="1024"/>
<!--开启注解调度支持 @Async @Scheduled-->
<task:annotation-driven executor="asyncExecutor" proxy-target-class="true"/>
(2)SpringBootの構成方法
@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;
}
}
使用する場合は、@Async
コメントを追加してください。
@Component
public class OrderEventListener implements SmartApplicationListener {
/**
* 支持的事件类型
*
* @param eventType
* @return
*/
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return eventType == OrderStatusMsgEvent.class;
}
/**
* 事件发生的目标类
*
* @param sourceType 事件发生的目标类类型
* @return
*/
@Override
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return true;
}
@Override
public int getOrder() {
return 0;
}
@Override
@Async
public void onApplicationEvent(ApplicationEvent applicationEvent) {
// 获取注册用户信息
OrderStatusMsgEvent orderStatusMsgEvent = (OrderStatusMsgEvent) applicationEvent;
OrderDTO orderInfo = orderStatusMsgEvent.getOrderDTO();
// 模拟kafka发送
// kafkaProducer.sendMsg(orderInfo);
System.out.println("======kafka发送成功====");
}
}
コード:https://github.com/nomico271/inspire-demo/tree/master/Ch2_SmartApplicationListener
リファレンス:https://segmentfault.com/a/1190000011433514