1 简介:

只要是事件就是观察者模式,Spring中的Event也不例外,主要应用就是程序解耦,实现本质是广播的形式........屁话不多说

2 Spring的event实现方式:

继承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  事件的推送:

编写事件推送的service实现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管理即可,实现有两种方式,

(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(); } }
7 java自带的事件:

(1)观察者模式:

作用: 解耦,解耦....其他都是废话

模式工作思想: a观察b,b做出某些动作后,a就及时的做动作的跟进(至于a做啥,看你需要他做啥)

设计思想:a根据b的状态变化做出响应,一般情况下都是多个对象观察一个对象,此时被观察者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(); }
被观察者:(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); } }

技术
今日推荐
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信