>  기사  >  Java  >  springboot 이벤트 리스너를 사용하는 방법

springboot 이벤트 리스너를 사용하는 방법

PHPz
PHPz앞으로
2023-05-14 10:01:20863검색

가이드 케이스

아래의 간단한 케이스를 살펴보겠습니다.

@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("发送邮件");
        }
    }

위 코드를 실행하고 효과를 관찰해 보세요

springboot 이벤트 리스너를 사용하는 방법

출력 결과와 합쳐서, 이 코드에서 구현할 로직은 메인라인 업무 이후에 실행이 완료되면 실행해야 합니다. 문자나 이메일을 보내는 등의 작성 작업에는 문제가 없지만 후속 업무 확장성 측면에서 충분히 우아하지 않고 친숙하지 않습니다. 또 다른 감사 작업을 추가해야 합니다. 새로운 코드 로직을 추가하면 메인 라인 비즈니스와 지사 라인 로직이 긴밀하게 연결됩니다.

즉, 우리가 기대하는 효과는 메인 라인 비즈니스가 다른 비즈니스 운영에 신경 쓰지 않는다는 것입니다. 이는 Spring에서 제공하는 이벤트 리스너 기능을 사용해야 합니다.

이벤트 리스너를 사용하는 변환 프로세스

springboot(spring)에서 이벤트 리스너를 사용하는 두 가지 주요 방법이 있습니다. , ApplicationListener 인터페이스를 구현하여 @EventListener 주석을 구현하는 것입니다. 다음으로 이 두 가지 메서드를 하나씩 설명합니다.

1. 이벤트 클래스(객체)를 사용자 정의하고 ApplicationEvent를 상속합니다

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

이렇게 이해하면 됩니다. 코드에는 다양한 유형의 이벤트가 있을 수 있으며, 서로 다른 비즈니스가 서로 다른 이벤트에 해당합니다. A 유형의 이벤트 수신

2. 클래스는 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 发邮件业务");
        }
    }

분명히 여기서 리스너가 수신하려는 이벤트 유형은 위에서 정의한 MyEvent입니다. 비즈니스가 트리거되면 전달된 매개변수를 onApplicationEvent에서 얻을 수 있으므로 문자 메시지 보내기(이메일 보내기) 작업이 실행됩니다

3. 메인 라인 비즈니스는 이벤트를 게시합니다
@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("发送邮件");
        }
    }

지금은 문자 메시지나 이메일을 보내는 로직을 작성할 필요가 없으며 게시자만 이벤트를 게시하면 됩니다. 매개변수를 전달해야 하는 경우 함께 전달하세요.

완전한 코드
@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 发邮件业务");
        }
    }
}

위를 실행하세요. 다시 코드를 작성하여 효과를 관찰해 보세요.

springboot 이벤트 리스너를 사용하는 방법 2. 통과 @EventListener 주석을 추가하여

이 메서드는 더 이상 ApplicationListener 인터페이스를 구현할 필요가 없습니다. @EventListener 주석을 청취 클래스의 메소드에 직접 추가하십시오. 전체 코드는

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 发邮件业务");
        }
    }
}

바로 아래에 게시됩니다. 위 코드를 실행하여 예상되는 효과도 얻을 수 있습니다

springboot 이벤트 리스너를 사용하는 방법 3. 비동기를 사용하세요

게다가 메인 라인 비즈니스의 로직 실행 효율성을 높이기 위해 이벤트 게시의 비즈니스 로직이 비동기로 실행되기를 바랍니다.

소스 코드를 살펴보면, 이벤트를 게시할 때 ApplicationEventPublisher가 기본적으로 단일 스레드 동기 전송을 사용하는 것을 볼 수 있습니다. 비동기식을 사용해야 하는 경우 ThreadPoolTaskExecutor 및 SimpleApplicationEventMulticaster를 사용자 정의해야 하므로 이 두 구성 요소의 Bean만 덮어쓰면 다음 두 가지를 추가할 수 있습니다.

@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;
    }

이때 코드를 다시 실행하고, 여러번 실행하면 효과를 볼 수 있습니다

springboot 이벤트 리스너를 사용하는 방법위의 단일 스레드 효과를 비교해 보세요

위 내용은 springboot 이벤트 리스너를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제