[JAVA] Étapes requises pour émettre des événements asynchrones Spring Boot

Spring Framework fournit un mécanisme qui vous permet d'enregistrer l'exécution d'une instance sous la gestion Spring en tant qu '«événement» et de contrôler l'exécution en émettant un événement. Il est simple à utiliser et Spring Boot permet un traitement asynchrone. Cette fois, nous décrirons un exemple d'implémentation du traitement asynchrone à l'aide d'événements asynchrones dans Spring Boot.

Environnement d'exploitation

Ce qui est nécessaire pour le traitement événementiel

Les 3 créations suivantes sont requises

Exemple d'implémentation

Événement à créer cette fois: reçoit une chaîne de caractères de la classe appelante et la renvoie dans le journal

La classe qui stocke la chaîne de caractères transmise par l'événement utilise ce qui suit.

SampleMessage.java


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

@AllArgsConstructor @Getter @ToString
public class SampleMessage {
	private String message;

	public static SampleMessage of(String message) {
		return new SampleMessage(message);
	}
}

Event

Hérite de org.springframework.context.ApplicationEvent.

PrimaryEvent.java


@Getter
public class PrimaryEvent extends ApplicationEvent {

	private final SampleMessage sampleMessage;

	public PrimaryEvent(Object source,  SampleMessage sampleMessage) {
		super(source);
		this.sampleMessage = sampleMessage;
	}

}

Premier argument du constructeur: Object source est une implémentation obligatoire.

Publisher

Créez une classe Java à l'aide de l'instance org.springframework.context.ApplicationEventPublisher gérée par Spring. Par conséquent, il est facile d'ajouter @ Component ou @ Service pour en faire une classe placée dans Spring management [^ 1].

PrimaryEventPublisher.java


import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;

@Component
@AllArgsConstructor
public class PrimaryEventPublisher {

	private final ApplicationEventPublisher applicationEventPublisher;

	public void ignite(String message) {
		SampleMessage sampleMessage = SampleMessage.of(message);
		
		//Créer un événement
		PrimaryEvent event = new PrimaryEvent(this, sampleMessage);

		//Emission d'événement!
		applicationEventPublisher.publishEvent(event);
	}
}

Listener

Placez-le sous Spring management [^ 2] et implémentez l'interface org.springframework.context.ApplicationListener. Le plus simple est de donner @ Component.

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import lombok.extern.log4j.Log4j2;

@Component
public class PrimaryEventListener implements ApplicationListener<PrimaryEvent>{

	@Override
	public void onApplicationEvent(PrimaryEvent event) {
		SampleMessage sampleMessage = event.getSampleMessage();
		
		//Traitement ultérieur après réception d'un message ↓......
	}

}

Ceci termine la préparation de l'exécution de l'événement.

Exemple d'exécution de Spring MVC Controller

Voici un exemple de réception d'une demande dans Controller, d'exécution d'un événement, puis d'affichage de l'écran.

DisplayController.java


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import lombok.AllArgsConstructor;

@RequestMapping("/display")
@Controller
@AllArgsConstructor
public class DisplayController {

	private final PrimaryEventPublisher publisher;

	@GetMapping
	public ModelAndView display(ModelAndView mnv) {

		publisher.ignite("Envoyer un message");

		mnv.setViewName("display");
		return mnv;
	}
}

Ce n'est pas différent de l'implémentation utilisant Spring MVC, et le contrôleur affiche l'écran une fois l'événement exécuté et terminé.

Traitement asynchrone

Pour utiliser le traitement asynchrone avec SpringBoot, donnez @ EnableAsync à la classe de démarrage SpringBoot, puis ajoutez @ Async à la classe que vous souhaitez effectuer un traitement asynchrone.

SpringEventSampleApplication.java


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class SpringEventSampleApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringEventSampleApplication.class, args);
	}

}

Par exemple, ce que vous souhaitez utiliser de manière asynchrone est la méthode ignite suivante dans le contrôleur.

DisplayController.java


public class DisplayController {

	private final PrimaryEventPublisher publisher;

	@GetMapping
	public ModelAndView display(ModelAndView mnv) {
		//Je souhaite le traiter séparément de l'affichage à l'écran
		publisher.ignite("Envoyer un message");

		mnv.setViewName("display");
		return mnv;
	}
}

Je veux exécuter PrimaryEventPublisher de manière asynchrone, alors ajoutez simplement @ Async.

PrimaryEventPublisher.java


import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import lombok.AllArgsConstructor;

@Component
@AllArgsConstructor
@Async
public class PrimaryEventPublisher {

	private final ApplicationEventPublisher applicationEventPublisher;

	public void ignite(String message) {
		SampleMessage sampleMessage = SampleMessage.of(message);

		PrimaryEvent event = new PrimaryEvent(this, sampleMessage);
		applicationEventPublisher.publishEvent(event);
	}
}

C'est très facile d (・ ω ・ ・ Puisqu'il est possible de sortir vers la source de données en utilisant @ Repository pour le traitement qui peut être exécuté, il peut également être utilisé pour envoyer une notification de fin de traitement à l'outil de discussion interne ou au courrier électronique.

[^ 1]: En fait, il peut être obtenu à partir de ApplicationContext de Spring, il n'est donc pas indispensable d'ajouter une annotation pour la placer sous la gestion Spring telle que @ Component. "Spring managed = classe enregistrée dans ApplicationContext". Dans Spring Boot, la fonction ComponentScan qui détecte l'existence de classes avec les annotations Spring @ Controller, @ Service, @ Repository et @ Component doit être dans un package valide. C'est une prémisse.

[^ 2]: car il est exécuté depuis ApplicationEventPublisher sous la gestion Spring. Si vous ne l'enregistrez pas dans ApplicationContext, cela ne fonctionnera pas (il sera manqué)

Recommended Posts

Étapes requises pour émettre des événements asynchrones Spring Boot
Spring.messages.fallback-to-system-locale: false est requis pour le message par défaut.properties pour la prise en charge i18n de Spring Boot
Introduction à Spring Boot + In-Memory Data Grid
Plans pour prendre en charge JDK 11 pour Eclipse et Spring Boot
Paramètres de connexion à MySQL avec Spring Boot + Spring JDBC
Comment définir l'injection de dépendance Spring Boot (DI)
Comment écrire un test unitaire pour Spring Boot 2
[Spring Boot] Comment créer un projet (pour les débutants)
De la création d'un environnement cloud AWS au déploiement d'une application Spring Boot (pour les débutants)
Essayez Spring Boot de 0 à 100.
Introduction à Spring Boot ① ~ DI ~
Introduction à Spring Boot ② ~ AOP ~
[Spring Boot] Envoyer un e-mail
Introduction à Spring Boot, partie 1
Spring Boot pour l'apprentissage des annotations
[Spring Boot] Que faire si une exception HttpMediaTypeNotAcceptableException se produit sur un point de terminaison pour lequel produit est défini
Comment créer un hinadan pour un projet Spring Boot à l'aide de SPRING INITIALIZR
02. J'ai créé une API pour me connecter de Spring Boot à MySQL (My Batis)
Traitement pour émettre un message d'erreur
Spring Boot pour la première fois
Créez une application avec Spring Boot 2
Comment configurer Spring Boot + PostgreSQL
Annotations fréquentes pour les tests Spring Boot
Créez une application avec Spring Boot
Utiliser DBUnit pour le test Spring Boot
Comment utiliser ModelMapper (Spring boot)
Mise à niveau de la botte à ressort de la série 1.5 à la série 2.0
Solution de contournement pour que Command Line Runner fonctionne avec JUnit dans Spring Boot
[Pour usage interne] Pour ceux affectés au projet Spring Boot (en construction)
Étapes pour créer une application chameau simple avec les démarreurs Apache Camel Spring Boot
[Introduction à Spring Boot] Vérification de la validation du formulaire
L'histoire de la transition de Spring Boot 1.5 à 2.1
Modifications lors de la migration de Spring Boot 1.5 vers Spring Boot 2.0
Mémorandum WebMvcConfigurer de Spring Boot 2.0 (printemps 5)
Modifications lors de la migration de Spring Boot 2.0 vers Spring Boot 2.2
Traitement asynchrone avec Spring Boot en utilisant @Async
Comment diviser un fichier de message Spring Boot
Ajoutez une botte de printemps et un dégradé à éclipse
[Résolution d'erreur] Se produit lors de la tentative de création d'un environnement pour le printemps avec docker
Lorsque vous souhaitez notifier une erreur quelque part lors de l'utilisation de graphql-spring-boot avec Spring Boot
De la création d'un projet Spring Boot à l'exécution d'une application avec VS Code