Модель, управляемая событиями, в Spring (1)

Java задняя часть Микросервисы Spring

Введение в модель, управляемую событиями

Модель, управляемая событиями, также обычно понимается как модель наблюдателя или модель публикации/подписки.

  • отношение «один ко многим» между объектами;
  • Когда цель отправляет изменения (опубликовывается), наблюдатели (подписчики) могут получать изменения;
  • Как обрабатывает наблюдатель, цели не нужно вмешиваться, и отношения между ними слабо связаны.

event-source
модель, управляемая событиями

Есть много примеров моделей, управляемых событиями, таких как светофоры в жизни и центр конфигурации, который мы используем в микросервисах, Когда конфигурация отправляется, конкретный экземпляр приложения отправляется для обновления контекста Spring.

Механизм событий Spring

Базовые концепты

Модель Spring, управляемая событиями, состоит из трех частей:

  • Событие: ApplicationEvent, унаследованное от EventObject JDK, все события будут наследоваться от него и получать источник события через источник.
  • Издатель событий: интерфейс ApplicationEventPublisher и ApplicationEventMulticaster, используя этот интерфейс, наш Сервис имеет возможность публиковать события.
  • Подписчик событий: ApplicationListener, унаследованный от EventListener JDK, его наследуют все слушатели.

Процесс, управляемый событиями Spring

событие

Spring по умолчанию предоставляет следующие реализации для событий ApplicationEvent:

  • ContextStoppedEvent: событие, инициированное после остановки ApplicationContext;
  • ContextRefreshedEvent: событие, инициированное после завершения инициализации или обновления ApplicationContext;
  • ContextClosedEvent: событие, инициированное после закрытия ApplicationContext. Например, когда веб-контейнер закрывается, автоматически срабатывает отключение контейнера Spring.Если это обычное java-приложение, его нужно вызватьctx.registerShutdownHook()Зарегистрируйте хук при выключении виртуальной машины;
  • ContextStartedEvent: событие, инициированное после запуска ApplicationContext;

eventobject
событие

public abstract class ApplicationEvent extends EventObject {
    private static final long serialVersionUID = 7099057708183571937L;
    //事件发生的时间
    private final long timestamp = System.currentTimeMillis();
	//创建一个新的ApplicationEvent事件
    public ApplicationEvent(Object source) {
        super(source);
    }

    public final long getTimestamp() {
        return this.timestamp;
    }
}

Базовый класс событийApplicationEvent, все конкретные события будут наследовать абстрактный класс событий.

прослушиватель событий

ApplicationListener
прослушиватель событий
ApplicationListenerунаследовано от JDKEventListener, JDK требует, чтобы все прослушиватели наследовались от него.

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
    void onApplicationEvent(E var1);
}

Предоставляет метод onApplicationEvent для обработкиApplicationEvent, но обработка конкретных событий требует оценки. иGenericApplicationListenerиSmartApplicationListenerПредоставляет дополнительные метаданные о событии.

public class SourceFilteringListener implements GenericApplicationListener, SmartApplicationListener {

	private final Object source;

	@Nullable
	private GenericApplicationListener delegate;

	//为特定事件源创建SourceFilteringListener,并传入代理的监听器类
	public SourceFilteringListener(Object source, ApplicationListener<?> delegate) {
		this.source = source;
		this.delegate = (delegate instanceof GenericApplicationListener ?
				(GenericApplicationListener) delegate : new GenericApplicationListenerAdapter(delegate));
	}
	//....省略部分代码
	
	@Override
	public int getOrder() {
		return (this.delegate != null ? this.delegate.getOrder() : Ordered.LOWEST_PRECEDENCE);
	}

	//过滤之后实际处理事件
	protected void onApplicationEventInternal(ApplicationEvent event) {
		//...
		this.delegate.onApplicationEvent(event);
	}

}

SourceFilteringListenerдаApplicationListenerКласс декоратора, который фильтрует определенные источники событий. Будет внедрен только прокси-слушатель, соответствующий его событию, а также предусмотрены такие функции, как последовательный запуск прослушивателя. Часть его будет загружаться при запускеApplicationListener. После завершения загрузки и инициализации Spring Context (обновление) приложение будет снова обнаружено.ApplicationListener, и зарегистрируйтесь, в это время мы будем реализовыватьApplicationListenerбудет добавлено кSimpleApplicationEventMulticasterв поддерживаемой коллекции Listener. Spring также поддерживает мониторинг событий в виде прямых аннотаций.@EventListener(Event.class).

выпуск события

EventPublisher
Опубликовать событие
ApplicationContextинтерфейс наследуетApplicationEventPublisher, И вAbstractApplicationContextРеализуется конкретный код, а фактическое выполнение делегируетсяApplicationEventMulticaster.

@FunctionalInterface
public interface ApplicationEventPublisher {
	//通知所有的注册该事件的应用,事件可以是框架事件如RequestHandledEvent或者特定的应用事件。
    default void publishEvent(ApplicationEvent event) {
        this.publishEvent((Object)event);
    }

    void publishEvent(Object var1);
}

Фактическое исполнение делегировано, заинтересованные читатели могут посмотретьAbstractApplicationContextлогика в этой части. Давайте посмотрим на это подробноApplicationEventMulticasterметоды, определенные в интерфейсе.

public interface ApplicationEventMulticaster {

	//增加监听者
	void addApplicationListener(ApplicationListener<?> listener);
	//...

	//移除监听者
	void removeApplicationListener(ApplicationListener<?> listener);
	//...
	
	//广播特定事件给监听者
	void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);

}

AbstractApplicationContextОн определяет работу и обслуживание прослушивателей, таких как добавление и удаление, и предоставляет методы для широковещательной передачи определенных событий. Давайте посмотрим на конкретный класс реализацииSimpleApplicationEventMulticaster.ApplicationContextАвтоматический поиск в локальном контейнереApplicationEventMulticasterреализация, если не будет использоваться значение по умолчаниюSimpleApplicationEventMulticaster.

public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {

	@Nullable
	private Executor taskExecutor;

	//...
	
	//用给定的beanFactory创建SimpleApplicationEventMulticaster
	public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {
		setBeanFactory(beanFactory);
	}

	@Override
	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			Executor executor = getTaskExecutor();
			if (executor != null) {
				executor.execute(() -> invokeListener(listener, event));
			}
			else {
				invokeListener(listener, event);
			}
		}
	}

	//注入给定事件的给定监听器
	protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
		ErrorHandler errorHandler = getErrorHandler();
		if (errorHandler != null) {
			try {
				doInvokeListener(listener, event);
			}
			...
		}
		else {
			doInvokeListener(listener, event);
		}
	}

	@SuppressWarnings({"unchecked", "rawtypes"})
	private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
		try {
			listener.onApplicationEvent(event);
		}
		//...
	}

}

существуетmulticastEventВ методе, если исполнитель не пустой, видно, что он поддерживает асинхронную публикацию событий. Просто позвоните, когда событие будет опубликованоApplicationContextсерединаpublishEventспособ публикации события.

Суммировать

В этой статье в основном представлены концепции, связанные с управляемой событиями моделью в Spring. Прежде всего, мы представим модель, управляемую событиями, также известную как шаблон наблюдателя, которая имеет множество применений в нашей повседневной жизни и разработке приложений. После этого в основном вводится механизм событий Spring. Модель Spring, управляемая событиями, состоит из трех частей: события, издатели и подписчики. В сочетании с исходным кодом Spring анализируются определения и реализации этих трех частей. В следующей статье автор объяснит реальный бой в сочетании с конкретными примерами и реализацией в Spring Cloud Config.

Подписывайтесь на свежие статьи, приглашаю обратить внимание на мой публичный номер

微信公众号

Ссылаться на

  1. Введение в модель, управляемую событиями
  2. Модель Spring, управляемая событиями, и шаблон наблюдателя