1 はじめに:
イベントである限りオブザーバーモードであり、Spring のイベントも例外ではなく、主なアプリケーションはプログラムのデカップリングであり、実装の本質はブロードキャストの形であるということです...あまりナンセンスではありません
2 Spring のイベント実装方法:
ApplicationEvent を継承できますが、Spring バージョン 4.2 以降では、ApplicationEvent の継承は必須ではなくなり、Application 以外のサブクラスは PayloadApplicationEvent にカプセル化されます。
達成:
import org.springframework.context.ApplicationEvent;
public class MyEvent extends ApplicationEvent {
//todo -----
private String msg;
public MyEvent(Object source) {
super(source);
}
public MyEvent(Object source,String msg) {
super(source);
this.msg=msg;
}
public String getMsg() {
return msg;
}
}
3 プッシュ イベント:
ApplicationContextAwar インターフェイスを実装するイベント プッシュ サービスを作成するか、ApplicationEventPublisherAware インターフェイスを実装し、必要に応じてビジネス シナリオに従ってイベントをプッシュします。
達成:
@Service
public class EventProduceService implements ApplicationContextAware, ApplicationEventPublisherAware {
//实现方式一
private ApplicationContext applicationContext;
//实现方式二
private ApplicationEventPublisher applicationEventPublisher;
/**
* 容器初始化时候会自动的填装该对象
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 容器初始化时候会自动的填装该对象
* @param applicationEventPublisher
*/
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher=applicationEventPublisher;
}
/**
* 实际业务中进行封装数据推送
*/
public void sentEvent(){
//方式一:applicationContext的推送Api可以以根据需要进行选择
applicationContext.publishEvent(new MyEvent(this,"我是一颗小码农"));
//方式二: applicationEventPublisher的推送Api可以以根据需要进行选择
applicationEventPublisher.publishEvent(new MyEvent(this,"今天是20220804"));
}
}
4 つのイベント リスナー (プロセッサ):
イベントハンドラを書いてSpringのioc管理に渡す 実装方法は2通りあります。
(1) 対応するイベント ハンドラーに @EventListener アノテーションを付けると、ハンドラーはパラメーターの型に応じてイベントの型を自動的に識別します。
達成:
@Configuration
public class EventConfig {
@EventListener
public void doWithEvent(MyEvent myEvent) {
System.out.println("事件消息是: "+myEvent.getMsg());
}
@EventListener
public void doWithEvent(BEvent myEvent) {
System.out.println("事件消息是: "+myEvent.getMsg());
}
@EventListener
public void doWithEvent(CEvent myEvent) {
System.out.println("事件消息是: "+myEvent.getMsg());
}
}
(2) ApplicationListener<T> インターフェイスを実装すると、プロセッサはジェネリック型に従ってイベントを処理します
達成
@Component
public class EventHandler implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
//todo----
System.out.println(event.getMsg());
}
}
5 つの非同期イベント:
Spring がデフォルトで監視するイベントはすべて同期です. 非同期イベントを実装するには, 非同期イベントのサポートを有効にする必要があります. 構成クラスで @EventListener アノテーションを使用して非同期サポートを有効にし, リスナーで @Async アノテーションを使用してマークします.同じイベント プロセッサに対する複数のイベントは、@Order アノテーションを使用して並べ替えることができます (パラメーターが小さいほど、優先度が高くなります)
達成:
@Configuration
@EnableAsync
public class EventConfig {
@Async
@EventListener
public void doWithEvent(MyEvent myEvent) {
System.out.println("事件消息是: "+myEvent.getMsg());
}
}
@Async//配置类已经开启异步支持
@Component
public class EventHandler implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
//todo----
System.out.println(event.getMsg());
}
}
6 イベント例外ハンドラ(イベントコンシューマで例外が発生した場合に必要な処理)
(1) 同期:
org.springframework.util.ErrorHandler を実装する例外ハンドラを作成する
import org.springframework.stereotype.Component;
import org.springframework.util.ErrorHandler;
//同步方式异常处理器
@Component
public class DoExphandler implements ErrorHandler {
/**
* 只要在SimpleApplicationEventMulticaster设置这个异常处理器,
* 事件消费方抛出异常就会触发这个方法中的异常,SimpleApplicationEventMulticaster.setErrorHandler(exphandler);
*/
@Override
public void handleError(Throwable e) {
if (e instanceof RuntimeException) {
//todo
} else {
}
}
}
SimpleApplicationEventMulticaster イベント ブロードキャストでコンシューマ イベントの例外ハンドラを設定する
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class EventProduceService implements ApplicationContextAware, ApplicationEventPublisherAware {
//实现方式一
private ApplicationContext applicationContext;
//实现方式二
private ApplicationEventPublisher applicationEventPublisher;
//事件推送类注入广播处理同步异常
@Autowired
private SimpleApplicationEventMulticaster saem;
@Autowired
private DoExphandler exphandler;
/**
* 容器初始化时候会自动的填装该对象
*
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 容器初始化时候会自动的填装该对象
*
* @param applicationEventPublisher
*/
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void sentEvent2(Object msg) {
applicationContext.publishEvent(new MyEvent2((String) msg));
}
/**
* 设置初始化的事件异常处理器
*/
@PostConstruct
public void init(){
saem.setErrorHandler(exphandler);
}
}
(2) 非同期:
非同期イベント ハンドラーの例外クラスを記述し、AsyncUncaughtExceptionHandler インターフェイスを実装する
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Component
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex,
Method method,
Object... params) {
//todo,做相关处理
ex.printStackTrace();
}
}
非同期イベントの例外構成を行います。
AsyncConfigurer インターフェースを実装する
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import java.util.concurrent.Executor;
@Configuration
public class AsyncConfig implements AsyncConfigurer {
@Autowired
private AsyncExceptionHandler asyncExceptionHandler;
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return asyncExceptionHandler;
}
@Override
public Executor getAsyncExecutor() {
System.out.println("getAsyncExecutor");
return AsyncConfigurer.super.getAsyncExecutor();
}
}
Java に付随する 7 つのイベント:
(1) オブザーバーモード:
機能: デカップリング、デカップリング...その他はナンセンス
パターン作業のアイデア: a は b を観察し、b が特定のアクションを実行した後、a は時間内にアクションをフォローアップします (a が何をするかについては、彼に何をする必要があるかによって異なります)。
設計思想: a は b の状態変化に応じて応答する. 一般に複数のオブジェクトが 1 つのオブジェクトを観察する. このとき, 観察されるオブジェクト b はどのオブジェクトが自分自身を観察しているかを認識する必要がある (これらのオブジェクトを格納するためのコレクションを設定する)
オブザーバー: (最上位インターフェースは java.util.Observer で作成されています)
public interface MyObserver {
void update(ObserverHandler handler);
}
class MyObserverImp implements MyObserver{
private int status;
/**
* 根据被观察者对象适应自身动作
* @param handler 被观察者对象
*/
@Override
public void update(ObserverHandler handler) {
status=((Handler)handler).getStatus();
}
Observable: (java.util. Observable が適応されました)
interface ObserverHandler {
//存储观察者,感知都有那些对象在观察
List<MyObserver> list = new ArrayList<>();
}
class Handler implements ObserverHandler {
private int status;
public void setStatus(int status) {
this.status = status;
updateAllStatus();
}
public int getStatus() {
return status;
}
public void updateAllStatus() {
for (MyObserver myObserver : list) {
myObserver.update(this);
}
}
public void addObserver(MyObserver observer) {
list.add(observer);
}
public void removeObserver(MyObserver observer) {
list.remove(observer);
}
}
(2) Java イベント:
イベント継承の作成 java.util.EventObject
public class UserEvent extends EventObject {
public UserEvent(Object source) {
super(source);
}
}
class SendMessageEvent extends UserEvent {
public SendMessageEvent(Object source) {
super(source);
}
}
class SendFileEvent extends UserEvent {
public SendFileEvent(Object source) {
super(source);
}
}
イベントリスナーの継承を作成します: java.util.EventListener
interface UserListener extends EventListener {
static final ConcurrentHashMap<Object, Object> map = new ConcurrentHashMap<>();
void doWithEvent(UserEvent event);
}
class Listener implements UserListener {
@Override
public void doWithEvent(UserEvent event) {
if (event instanceof SendFileEvent) {
System.out.println(event);
} else if (event instanceof SendMessageEvent) {
System.out.println(event);
}
}
}
プッシュイベント:
class SendEventHandler {
private static UserListener listener = new Listener();
public static void main(String[] args) {
final SendMessageEvent sentMessage = new SendMessageEvent("发送事件");
final SendFileEvent sendFile = new SendFileEvent("发送文件");
listener.doWithEvent(sentMessage);
listener.doWithEvent(sendFile);
}
}