Maison  >  Article  >  Java  >  Comment utiliser l'écouteur d'événements Springboot

Comment utiliser l'écouteur d'événements Springboot

PHPz
PHPzavant
2023-05-14 10:01:20904parcourir

Cas guide

Regardons un cas simple ci-dessous,

@Configuration
public class SelfBusiness {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SelfBusiness.class);
        context.getBean(MyService.class).doBusiness();
        context.close();
    }
    @Component
    static class MyService {
        private static final Logger logger = LoggerFactory.getLogger(MyService.class);
        @Autowired
        private ApplicationEventPublisher publisher;
        public void doBusiness (){
            logger.debug("主线业务");
            logger.debug("发送短信");
            logger.debug("发送邮件");
        }
    }

Exécutez le code ci-dessus et observez l'effet

Comment utiliser lécouteur dévénements Springboot

Combinée aux résultats de sortie, la logique à implémenter par ce code est qu'après la ligne principale d'activité l'exécution est terminée, elle doit être exécutée. Il n'y a rien de mal à écrire des opérations telles que l'envoi de messages texte et d'e-mails, mais ce n'est pas assez élégant et pas assez convivial en termes d'évolutivité commerciale ultérieure. une autre opération d'audit doit être ajoutée, c'est nécessaire L'ajout d'une nouvelle logique de code couple étroitement la logique d'activité principale et la logique d'embranchement

C'est-à-dire que l'effet que nous attendons est que l'activité principale ne se soucie pas des autres opérations commerciales ; du tout, et n'a besoin que de compléter sa propre logique. Cela nécessite l'utilisation de la fonction d'écoute d'événement fournie par spring

Le processus de transformation de l'utilisation des écouteurs d'événement

Il existe deux manières principales d'utiliser les écouteurs d'événement dans springboot (spring) ; , en implémentant l'interface ApplicationListener, et l'autre consiste à l'ajouter à la classe. L'annotation @EventListener est implémentée. Ensuite, ces deux méthodes seront expliquées une par une

1. Personnalisez une classe d'événement (objet) et héritez d'ApplicationEvent

 static class MyEvent extends ApplicationEvent {
        public MyEvent(Object source) {
            super(source);
        }
    }

Cela peut être compris ainsi, dans le code, il peut y avoir de nombreux types d'événements, et différentes entreprises correspondent à différents événements. Pour un auditeur spécifique, il veut seulement. écouter les événements de type A 

2. Custom business La classe implémente l'interface ApplicationListener
  
	@Data
    static class Params {
        private String id ;
        private String name;
        private String phone;
    }
	@Component
    static class SmsApplicationListener implements ApplicationListener<MyEvent> {
        private static final Logger logger = LoggerFactory.getLogger(SmsApplicationListener.class);
        @Override
        public void onApplicationEvent(MyEvent myEvent) {
            Object source = myEvent.getSource();
            try {
                Params params = objectMapper.readValue(source.toString(), Params.class);
                logger.debug("userId : {}",params.getId());
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            logger.debug("执行 sms 发短信业务");
        }
    }
    @Component
    static class EmailApplicationListener implements ApplicationListener<MyEvent> {
        private static final Logger logger = LoggerFactory.getLogger(SmsApplicationListener.class);
        @Override
        public void onApplicationEvent(MyEvent myEvent) {
            Object source = myEvent.getSource();
            logger.debug("执行 email 发邮件业务");
        }
    }

De toute évidence, le type d'événement que l'auditeur veut écouter ici est exactement le MyEvent que nous avons défini ci-dessus, de cette façon. l'activité est déclenchée, les paramètres transmis peuvent être obtenus dans onApplicationEvent, ainsi L'opération commerciale d'envoi de messages texte (envoi d'e-mails) est exécutée

3 L'activité principale publie des événements
@Component
    static class MyService {
        private static final Logger logger = LoggerFactory.getLogger(MyService.class);
        @Autowired
        private ApplicationEventPublisher publisher;
        public void doBusiness (){
            Params params = new Params();
            params.setId("001");
            params.setName("xiaoma");
            params.setPhone("133******");
            logger.debug("主线业务");
            try {
                publisher.publishEvent(new MyEvent(objectMapper.writeValueAsString(params)));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            //publisher.publishEvent(new MyEvent("MyService doBusiness()"));
            //logger.debug("发送短信");
            //logger.debug("发送邮件");
        }
    }

Pour l'activité principale, il y a. pas besoin d'écrire la logique d'envoi de SMS ou d'e-mails pour le moment, seul un éditeur est nécessaire pour publier les événements. Sortez simplement Si vous devez transmettre des paramètres, transmettez-les ensemble

Code complet
@Configuration
public class SelfBusiness {
    private static ObjectMapper objectMapper = new ObjectMapper();
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SelfBusiness.class);
        context.getBean(MyService.class).doBusiness();
        context.close();
    }
    @Data
    static class Params {
        private String id ;
        private String name;
        private String phone;
    }
    /**
     * 自定义事件对象
     */
    static class MyEvent extends ApplicationEvent {
        public MyEvent(Object source) {
            super(source);
        }
    }
    @Component
    static class MyService {
        private static final Logger logger = LoggerFactory.getLogger(MyService.class);
        @Autowired
        private ApplicationEventPublisher publisher;
        public void doBusiness (){
            Params params = new Params();
            params.setId("001");
            params.setName("xiaoma");
            params.setPhone("133******");
            logger.debug("主线业务");
            try {
                publisher.publishEvent(new MyEvent(objectMapper.writeValueAsString(params)));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            //publisher.publishEvent(new MyEvent("MyService doBusiness()"));
            //logger.debug("发送短信");
            //logger.debug("发送邮件");
        }
    }
    /**
     * 监听事件触发后要执行的业务
     */
    @Component
    static class SmsApplicationListener implements ApplicationListener {
        private static final Logger logger = LoggerFactory.getLogger(SmsApplicationListener.class);
        @Override
        public void onApplicationEvent(MyEvent myEvent) {
            Object source = myEvent.getSource();
            try {
                Params params = objectMapper.readValue(source.toString(), Params.class);
                logger.debug("userId : {}",params.getId());
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            logger.debug("执行 sms 发短信业务");
        }
    }
    @Component
    static class EmailApplicationListener implements ApplicationListener {
        private static final Logger logger = LoggerFactory.getLogger(SmsApplicationListener.class);
        @Override
        public void onApplicationEvent(MyEvent myEvent) {
            Object source = myEvent.getSource();
            logger.debug("执行 email 发邮件业务");
        }
    }
}

Exécutez ce qui précède. codez à nouveau et observez l'effet. Vous pouvez voir qu'il peut toujours répondre à l'effet attendu

Comment utiliser lécouteur dévénements Springboot 2. Passez Ajoutez l'annotation @EventListener pour réaliser

Cette méthode n'a plus besoin d'implémenter l'interface ApplicationListener, mais ajoutez simplement le Annotation @EventListener directement à la méthode de la classe d'écoute. C'est relativement simplifié. Le code complet est publié directement ci-dessous

package com.congge.config;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Configuration
public class SelfBusiness2 {
    private static ObjectMapper objectMapper = new ObjectMapper();
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SelfBusiness2.class);
        context.getBean(MyService.class).doBusiness();
        context.close();
    }
    @Data
    static class Params {
        private String id ;
        private String name;
        private String phone;
    }
    /**
     * 自定义事件对象
     */
    static class MyEvent extends ApplicationEvent {
        public MyEvent(Object source) {
            super(source);
        }
    }
    @Component
    static class MyService {
        private static final Logger logger = LoggerFactory.getLogger(MyService.class);
        @Autowired
        private ApplicationEventPublisher publisher;
        public void doBusiness (){
            Params params = new Params();
            params.setId("001");
            params.setName("xiaoma");
            params.setPhone("133******");
            logger.debug("主线业务");
            try {
                publisher.publishEvent(new MyEvent(objectMapper.writeValueAsString(params)));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
    }
    @Component
    static class SmsListenerService {
        private static final Logger logger = LoggerFactory.getLogger(SmsListenerService.class);
        @EventListener
        public void smsListener(MyEvent myEvent){
            Object source = myEvent.getSource();
            try {
                SelfBusiness2.Params params = objectMapper.readValue(source.toString(), SelfBusiness2.Params.class);
                logger.debug("userId : {}",params.getId());
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            logger.debug("执行 sms 发短信业务");
        }
    }
    @Component
    static class EmailListenerService {
        private static final Logger logger = LoggerFactory.getLogger(EmailListenerService.class);
        @EventListener
        public void emailListener(MyEvent myEvent){
            Object source = myEvent.getSource();
            try {
                SelfBusiness2.Params params = objectMapper.readValue(source.toString(), SelfBusiness2.Params.class);
                logger.debug("userId : {}",params.getId());
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            logger.debug("执行 email 发邮件业务");
        }
    }
}

Exécutez le code ci-dessus et observez l'effet

Comment utiliser lécouteur dévénements Springboot3. Utiliser l'asynchrone

De plus, afin d'améliorer l'efficacité de l'exécution de la logique de l'activité principale, nous espérons que la logique métier des événements de publication sera exécutée de manière asynchrone. Ceci Comment faire ? voyez que ApplicationEventPublisher utilise par défaut l'envoi synchrone à un seul thread lors de la publication d'événements. Si vous devez utiliser l'asynchrone, vous devez personnaliser ThreadPoolTaskExecutor et SimpleApplicationEventMulticaster, nous n'avons donc besoin que d'écraser les beans de ces deux composants et d'ajouter les deux beans suivants. la classe affaires ci-dessus ;

@Bean
    public ThreadPoolTaskExecutor executor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        return executor;
    }
    @Bean
    public SimpleApplicationEventMulticaster applicationEventMulticaster(ThreadPoolTaskExecutor executor) {
        SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster();
        eventMulticaster.setTaskExecutor(executor);
        return eventMulticaster;
    }

Exécutez à nouveau le code à ce moment-là, exécutez-le plusieurs fois et vous pourrez voir l'effet

Comparez l'effet monothread ci-dessus

Comment utiliser lécouteur dévénements Springboot

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer