@EventListener注解的使用以及工作原理解读(观察者模

2021-12-31  本文已影响0人  Raral

@EventListener注解的使用以及工作原理解读(观察者模式)

在开发工作中,会遇到一种场景,做完某一件事情以后,需要广播一些消息或者通知,告诉其他的模块进行一些事件处理,一般来说,可以一个一个发送请求去通知,但是有一种更好的方式,那就是事件监听,事件监听也是设计模式中 发布-订阅模式、观察者模式的一种实现。

观察者模式:简单的来讲就是你在做事情的时候身边有人在盯着你,当你做的某一件事情是旁边观察的人感兴趣的事情的时候,他会根据这个事情做一些其他的事,但是盯着你看的人必须要到你这里来登记,否则你无法通知到他(或者说他没有资格来盯着你做事情)

简介

要想顺利的创建监听器,并起作用,这个过程中需要这样几个角色:

ApplicationListener 接口

它是一个泛型接口,泛型的类型必须是ApplicationEvent 及其子类,只要实现了这个接口,那么当容器有相应的事件触发时,就能触发 onApplicationEvent 方法。ApplicationEvent 类的子类有很多,Spring 框架自带的如下几个。

简单使用

@Component
public class DefinitionApplicationListener implements ApplicationListener<ApplicationEvent> {

    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        System.out.println("事件触发:" + applicationEvent.getClass().getName());
    }
}


2021-12-31 15:41:01.727  INFO 2076 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8001 (http) with context path ''
事件触发:org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent
事件触发:org.springframework.boot.builder.ParentContextApplicationContextInitializer$ParentContextAvailableEvent
事件触发:org.springframework.boot.context.event.ApplicationPreparedEvent
事件触发:org.springframework.context.event.ContextRefreshedEvent
2021-12-31 15:41:02.105  INFO 2076 --- [  restartedMain] a.s.CloudProvider2Payment8001Application : Started CloudProvider2Payment8001Application in 3.84 seconds (JVM running for 5.469)
事件触发:org.springframework.boot.context.event.ApplicationStartedEvent
事件触发:org.springframework.boot.availability.AvailabilityChangeEvent
事件触发:org.springframework.boot.context.event.ApplicationReadyEvent
事件触发:org.springframework.boot.availability.AvailabilityChangeEvent
=Payment8001Application启动成功=

相当于spring一些自动装配的事件触发会执行这个监听函数

例子实现

实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
    private Integer id;
    private String name;
}

自定义事件

public class UserEvent extends ApplicationEvent {

    //实现父类方法
    public UserEvent(Object source) {
        super(source);
    }
}

自定义监听器

//监听器, 可以接受到 发送的事件
@Component
//方式一:通过@EvnetListener,简单易用,扩展性高
public class UserListener {

    //监听器1
    @EventListener
    public void getUserEvent(UserEvent userEvent) {
        System.out.println("getUserEvent-接受到事件(发送短信):" + userEvent);
    }
    //监听器2
    @EventListener
    public void getUserEvent2(UserEvent userEvent) {
        System.out.println("getUserEvent2-接受到事件(发送邮箱):" + userEvent);
    }

}
//方式二:通过实现接口,来定义监听器;不方便扩展
//public class UserListener implements ApplicationListener<UserEvent> {
//
//    //只监听UserEvent事件
//    @Override
//    public void onApplicationEvent(UserEvent userEvent) {
//        System.out.println("getUserEvent-接受到事件(发送短信):" + userEvent);
//    }
//}

发送事件(业务层Service)

//发送事件
@Service
public class UserService implements ApplicationContextAware, ApplicationEventPublisherAware {
    private ApplicationContext applicationContext;
    private ApplicationEventPublisher applicationEventPublisher;

    //设置应用上下文
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    //设置应用事件发布
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    //新增用户
    public String addUser(User user) {
        User u = User.builder().id(1).name("xiaoming").build();
        //发送事件,事件参数是user (第一种方式)
//        applicationContext.publishEvent(new UserEvent(u));
        //第二种方式
        applicationEventPublisher.publishEvent(new UserEvent(u));

        return "发送ok";
    }
}

控制层

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("test/event")
    public String testEvent() {
        return userService.addUser(new User());
    }
}

启动springboot项目,验证测试接口

=Payment8001Application启动成功=
2021-12-31 16:48:26.699  INFO 5220 --- [nio-8001-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-12-31 16:48:26.699  INFO 5220 --- [nio-8001-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-12-31 16:48:26.704  INFO 5220 --- [nio-8001-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 5 ms
getUserEvent-接受到事件(发送短信):com.atguigu.springcloud.common.eventListener.UserEvent[source=User(id=1, name=xiaoming)]
getUserEvent2-接受到事件(发送邮箱):com.atguigu.springcloud.common.eventListener.UserEvent[source=User(id=1, name=xiaoming)]
上一篇 下一篇

猜你喜欢

热点阅读