目录
观察者模式
废话不多说,直接上代码 我相信看代码比文字来的更加明白
主题 Subject
package com.ruoyi.observermodel;
import java.util.ArrayList;
import java.util.List;
/**
* 抽象主题类(作用是通知观察者)
*@Author:luyongcheng
*@Date:2024/11/8 10:18
*/
public abstract class Subject {
// 定义观察者集合
private List<Observer> observers = new ArrayList<>();
/**
* 增加观察者
*/
public void addObserver(Observer observer) {
observers.add(observer);
}
/**
* 删除观察者
*/
public void removeObserver(Observer observer) {
observers.remove(observer);
}
/**
* 通知注册该主题的观察者
*/
public void notifyObservers(Object message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
主题的具体实现 ObserverImpl
package com.ruoyi.observermodel;
import lombok.Data;
import lombok.experimental.Accessors;
/**
*@Author:luyongcheng
*@Date:2024/11/8 10:47
*/
@Data
@Accessors(chain = true)
public class ObserverImpl implements Observer {
private String name;
@Override
public void update(Object message) {
// 业务逻辑实现
System.out.println("观察者:" + name + ",接收到主题的消息: " + message);
}
}
观察者 Observer
package com.ruoyi.observermodel;
/**
* 观察者接口
*@Author:luyongcheng
*@Date:2024/11/8 10:19
*/
public interface Observer {
void update(Object message);
}
观察者具体实现 ObserverImpl
package com.ruoyi.observermodel;
import lombok.Data;
import lombok.experimental.Accessors;
/**
*@Author:luyongcheng
*@Date:2024/11/8 10:47
*/
@Data
@Accessors(chain = true)
public class ObserverImpl implements Observer {
private String name;
@Override
public void update(Object message) {
// 业务逻辑实现
System.out.println("观察者:" + name + ",接收到主题的消息: " + message);
}
}
客户端调用 ObserverModelClient
package com.ruoyi.observermodel;
/**
*@Author:luyongcheng
*@Date:2024/11/8 10:48
*/
public class ObserverModelClient {
public static void main(String[] args) {
SubjectImpl subject = new SubjectImpl();
subject.addObserver(new ObserverImpl().setName("1"));
subject.addObserver(new ObserverImpl().setName("2"));
subject.addObserver(new ObserverImpl().setName("3"));
subject.notifyObservers("主题状态发生变化!");
}
}
总结:
Observer 注册到Subject ,SUbject调用 notifyObservers(Object message) 方法 通知观察者主题发生了变化
主题------>消息传递------>观察者
监听器模式
同样上代码
事件源EventSource
package com.ruoyi.listenermode;
import java.util.ArrayList;
import java.util.List;
/**
*@Author:luyongcheng
*@Date:2024/11/8 11:00
*/
public class EventSource {
private List<EventListener> listeners = new ArrayList<>();
/**
* 添加监听器
* @param listener
*/
public void addListener(EventListener listener) {
listeners.add(listener);
}
/**
* 移除监听器
* @param listener
*/
public void removeListener(EventListener listener) {
listeners.remove(listener);
}
public void notifyAll(Event event) {
for (EventListener listener : listeners) {
listener.onClick(event);
}
}
}
事件 Event
package com.ruoyi.listenermode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*@Author:luyongcheng
*@Date:2024/11/8 10:58
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Event {
/**
* 数据
*/
private String data;
/**
* 类型
*/
private String type;
}
事件监听器抽象类 EventListener
package com.ruoyi.listenermode;
/**
*@Author:luyongcheng
*@Date:2024/11/8 11:01
*/
@FunctionalInterface
public interface EventListener {
/**
* 点击事件
* @param event
*/
void onClick(Event event);
}
客户端调用ListenerModeClient
package com.ruoyi.listenermode;
/**
*@Author:luyongcheng
*@Date:2024/11/8 11:05
*/
public class ListenerModeClient {
public static void main(String[] args) {
EventSource eventSource = new EventSource();
eventSource.addListener(event -> System.out.println("listener1: " + event.getData() + "," + event.getType()));
eventSource.notifyAll(new Event("hello world", "click"));
}
}
总结:
事件监听器注册到时间源,事件源调用notifyAll(Even enen)方法 执行事件监听器实现类方法
事件源------>传递事件------>事件监听器
Spring监听器源码分析
事件源
事件 增加了 事件广播器 负责把事件传给时间监听器 实现了事件源和时间监听器的解耦合 增加了这一层 这一层就是事件广播器
事件监听器
事件源
ApplicationContext 是Spring的容器 继承了ApplicationEventPublisher ,这类有发布事件的方法所以ApplicationContext可以作为时间源类
事件
ApplicationEvent 继承了 EventObject 这个类有可以获取到Source信息
事件监听器
ApplicationListener 继承了 EventListener 这个类有一个方法onApplicationEnent 监听器的执行方法 multicastEvent(ApplicationEvent event)
事件广播器
ApplicationEventMulticaster 把AppliactionContext 发布的ApplicationEven 传递给 AppliactionListener 用到的方法 multicastEvent
源码分析
在AbstractApplicationContext的refresh() 方法中 有
// 初始化事件广播器
initApplicationEventMulticaster();
深入方法内
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断工厂容器是否有时间广播器 如果没有new一个 放到工厂容器里面
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
// 注册监听器
registerListeners();
深入到方法
protected void registerListeners() {
// Register statically specified listeners first.
// 注册事件监听器到事件广播器也就是事件管理器里面
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
// 此时是事件管理器发布事件到事件监听器
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
finishRefresh(); 完成刷新
深入到方法
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 执行事件监听器
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!NativeDetector.inNativeImage()) {
LiveBeansView.registerApplicationContext(this);
}
}
继续深入publishEvent(new ContextRefreshedEvent(this));
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
继续深入
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
继续深入getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
继续深入executor.execute(() -> invokeListener(listener, event));
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
继续深入doInvokeListener(ApplicationListener listener, ApplicationEvent event);
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass()) ||
(event instanceof PayloadApplicationEvent &&
matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception.
Log loggerToUse = this.lazyLogger;
if (loggerToUse == null) {
loggerToUse = LogFactory.getLog(getClass());
this.lazyLogger = loggerToUse;
}
if (loggerToUse.isTraceEnabled()) {
loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
listener.onApplicationEvent(event); 大家看到这行代码恍然大悟了吗

有很多事件实现的方法 自己Debug去看吧 在SpringBoot框架中 监听器贯穿了整个SpringBoot启动过程
自定义Spring监听器
事件
package com.ruoyi.customListeners;
import org.springframework.context.ApplicationEvent;
/**
*@Author:luyongcheng
*@Date:2024/11/8 12:50
*/
public class OrderEvent extends ApplicationEvent {
private String name;
public OrderEvent(Object source, String name) {
super(source);
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
事件监听器
package com.ruoyi.customListeners;
import org.springframework.context.ApplicationListener;
/**
*@Author:luyongcheng
*@Date:2024/11/8 12:51
*/
public class OrderEventListener implements ApplicationListener<OrderEvent> {
@Override
public void onApplicationEvent(OrderEvent event) {
System.out.println("event.getName() = " + event.getName());
}
}
客户端调用
package com.ruoyi.customListeners;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
*@Author:luyongcheng
*@Date:2024/11/8 12:52
*/
public class CustomListenersClient {
public static void main(String[] args) {
// 创建事件源
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(XXX.class);
// 发布事件 source 是事件数据 name 也是
context.publishEvent(new OrderEvent(source, name));
}
}
Spring监听器模式与源码分析

被折叠的 条评论
为什么被折叠?



