设计模式-类交互-发布订阅

发布订阅

这种事情,NIO,消息队列 最熟了。

1. 订阅者 订阅事件

2. 发布者 发布事件

3. 订阅者接收事件

Spring事件

先看Spring 事件,典型的发布订阅模式,用于组件间通知。

https://docs.spring.io/spring-framework/docs/5.3.27/reference/html/core.html#context-functionality-events

发布者 Publisher -消息 Event->  监听者 Listener,用Spring实现就是

1. 定义Event extends ApplicationEvent

2. @Autowired ApplicationEventPublisher#publishEvent(new Event());

3. 配置类 方法上标注 @EventListener(classes = {Event.class})

看实现

spring-aop-5.3.22.jar

功能:执行完目标对象方法后发布一个自定义事件并用监听器监听

// from org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
/**
 * {@link MethodInterceptor Interceptor} that publishes an
 * {@code ApplicationEvent} to all {@code ApplicationListeners}
 * registered with an {@code ApplicationEventPublisher} after each
 * <i>successful</i> method invocation.
 *
 * <p>Note that this interceptor is only capable of publishing <i>stateless</i>
 * events configured via the
 * {@link #setApplicationEventClass "applicationEventClass"} property.
 *
 * @author Dmitriy Kopylenko
 * @author Juergen Hoeller
 * @author Rick Evans
 * @see #setApplicationEventClass
 * @see org.springframework.context.ApplicationEvent
 * @see org.springframework.context.ApplicationListener
 * @see org.springframework.context.ApplicationEventPublisher
 * @see org.springframework.context.ApplicationContext
 */
public class EventPublicationInterceptor
		implements MethodInterceptor, ApplicationEventPublisherAware, InitializingBean {

    // 目标方法执行后发布事件
	public Object invoke(MethodInvocation invocation) throws Throwable {
        // 执行目标方法
		Object retVal = invocation.proceed();

		Assert.state(this.applicationEventClassConstructor != null, "No ApplicationEvent class set");
        // 构建事件体,入参 是目标方法
		ApplicationEvent event = (ApplicationEvent)
				this.applicationEventClassConstructor.newInstance(invocation.getThis());

		Assert.state(this.applicationEventPublisher != null, "No ApplicationEventPublisher available");
        // 方法拦截链 存在事件,发布事件
		this.applicationEventPublisher.publishEvent(event);

		return retVal;
	}
}

// from getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);

// org.springframework.context.event.SimpleApplicationEventMulticaster#multicastEvent(org.springframework.context.ApplicationEvent, org.springframework.core.ResolvableType)
// 广播事件
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);
		}
	}
}

// 	listener存储	
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
// listener 从容器中取 
ApplicationListener<?> listener = beanFactory.getBean(listenerBeanName,ApplicationListener.class);


// org.springframework.context.event.SimpleApplicationEventMulticaster#doInvokeListener
listener.onApplicationEvent(event);


// org.springframework.context.event.ApplicationL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值