Maison > Java > javaDidacticiel > Comment implémenter le mode d'écoute SpringBoot

Comment implémenter le mode d'écoute SpringBoot

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
Libérer: 2023-05-20 19:07:19
avant
1098 Les gens l'ont consulté

Prenons l'événement de démarrage de l'application : ApplicationStartingEvent comme exemple pour illustrer :

Prenons la méthode SpringApplication.run de la classe de démarrage comme point d'entrée Après avoir suivi les deux méthodes du même nom dans SpringApplication, nous verrons l'exécution principale. méthode, qui est relativement longue, seules les parties clés étroitement liées à l'auditeur sont postées ici :

SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
Copier après la connexion

Nous faisons suite à cette méthode de départ, le contenu de la méthode est le suivant :

void starting() {
	for (SpringApplicationRunListener listener : this.listeners) {
		listener.starting();
	}
}
Copier après la connexion

Les auditeurs ici ont été chargés. dans la méthode getRunListeners, et le principe de chargement est similaire à celui de l'initialiseur système. Concernant le chargement de l'initialiseur système, vous pouvez vous référer à l'analyse approfondie des initialiseurs de SpringBoot. La logique de la méthode de démarrage est très simple, qui consiste à appeler le démarrage. méthode de SpringApplicationRunListener. Continuons à analyser cette méthode de démarrage :

Nous entrons dans la méthode de démarrage de la classe EventPublishingRunListener (classe d'implémentation de SpringApplicationRunListener) :

	@Override
	public void starting() {
		this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
	}
Copier après la connexion

Un diffuseur est utilisé ici pour diffuser le nouvel événement ApplicationStartingEvent.

Nous suivons cette méthode multicastEvent :

	@Override
	public void multicastEvent(ApplicationEvent event) {
		multicastEvent(event, resolveDefaultEventType(event));
	}
Copier après la connexion

Continuons à regarder la méthode multicastEvent du même nom :

	@Override
	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);
			}
		}
	}
Copier après la connexion

Le ResolvableType ici enveloppe l'événement, nous n'y prêtons donc pas attention puisque nous n'avons pas créé de ; pool de threads, l’exécuteur est vide. Nous nous concentrons sur deux parties :

Obtenir que tous les auditeurs d'application écoutent cet événement

2. InvoquerListener --> Activer l'écouteur ;

getApplicationListeners (dans la classe AbstractApplicationEventMulticaster), le code est le suivant :

	protected Collection<ApplicationListener<?>> getApplicationListeners(
			ApplicationEvent event, ResolvableType eventType) {
		Object source = event.getSource();
		Class<?> sourceType = (source != null ? source.getClass() : null);
		ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
		// Quick check for existing entry on ConcurrentHashMap...
		ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
		if (retriever != null) {
			return retriever.getApplicationListeners();
		}
		if (this.beanClassLoader == null ||
				(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
						(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
			// Fully synchronized building and caching of a ListenerRetriever
			synchronized (this.retrievalMutex) {
				retriever = this.retrieverCache.get(cacheKey);
				if (retriever != null) {
					return retriever.getApplicationListeners();
				}
				retriever = new ListenerRetriever(true);
				Collection<ApplicationListener<?>> listeners =
						retrieveApplicationListeners(eventType, sourceType, retriever);
				this.retrieverCache.put(cacheKey, retriever);
				return listeners;
			}
		}
		else {
			// No ListenerRetriever caching -> no synchronization necessary
			return retrieveApplicationListeners(eventType, sourceType, null);
		}
	}
Copier après la connexion

Entrez le paramètres L'événement dans est ApplicationStartingEvent et le sourceType est la classe org.springframework.boot.SpringApplication. Je considère le type ListenerRetriever comme un conteneur qui stocke les écouteurs.

On voit que le programme recherche d'abord un récupérateur de type ListenerRetriever dans le cache, s'il n'est pas trouvé, il le verrouille et le recherche à nouveau dans le cache. Il n'y a aucun contenu dans notre cache ici, il ne sera donc pas renvoyé.

Utilisez ensuite la méthode retrieveApplicationListeners pour parcourir les écouteurs. La méthode retrieveApplicationListeners est relativement longue.Nous nous concentrons sur la méthode supportsEvent(listener, eventType, sourceType) Cette méthode est utilisée pour déterminer si cet écouteur prête attention à l'événement.Le processus consiste principalement à déterminer si ce type est un type GenericApplicationListener. non, en construisant un proxy. Le but du proxy est d'obtenir finalement les événements qui intéressent l'auditeur grâce à une analyse générique.

S'il est déterminé que l'auditeur est intéressé par l'événement, l'auditeur sera ajouté à la liste des auditeurs.

	protected boolean supportsEvent(
			ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
		GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
				(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
		return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
	}
Copier après la connexion

Lorsque tous les écouteurs d'un événement sont collectés, la méthode multicastEvent (classe SimpleApplicationEventMulticaster) propagera l'événement. Autrement dit, appelez la méthode d'interface de déclenchement générale de l'écouteur : Listener.onApplicationEvent(event); De cette façon, la propagation de cet événement est terminée.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal