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.
Les 3 créations suivantes sont requises
É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.
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é.
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