美文网首页
@EventListener注解的使用以及工作原理解读(观察者模

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

作者: Raral | 来源:发表于2021-12-31 16:58 被阅读0次

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

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

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

简介

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

  • 事件(event)可以封装和传递监听器中要处理的参数,如对象或字符串,并作为监听器中监听的目标。
  • 监听器(listener)具体根据事件发生的业务处理模块,这里可以接收处理事件中封装的对象或字符串。
  • 事件发布者(publisher)事件发生的触发者。

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)]

相关文章

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

    @EventListener注解的使用以及工作原理解读(观察者模式) 在开发工作中,会遇到一种场景,做完某一件事情...

  • Spring Cloud Hystrix 分析(四)之Zuul集

    前面的几节我们重点分析了Hystrix的整个流程以及工作原理,以及基于@HystrixCommand注解使用方式之...

  • KVO的使用以及原理

    iOS KVO的使用以及原理 简介 KVO:(Key - Value - Observer) 键值观察者,是观察者...

  • 注解

    注解实现原理 底层使用反射实现。申明注解类需要加 @interface 注解类里只支持基本类型、String以及枚...

  • EventBus

    组件间通信除了Arouter,EventBus常用来发布/订阅事件,类似观察者模式,核心原理是注解和反射,基本使用...

  • 优雅编程-自定义注解使用及元注解@interface 详细解读

    优雅编程-自定义注解使用及元注解@interface 详细解读 相关注解解读(目前一共 6个) @Target T...

  • 23种设计模式之观察者模式

    观察者模式底层实现 使用java.util.Observable,java.util.Observer实现观察者模...

  • supervisor

    使用supervisor WatchDog监控进程 使用eventlistener:crashmail-exite...

  • RxJava观察者模式

    1.点击事件的观察者模式: 2.通用观察者模式: 3.RxJava的观察者模式 RxJava使用的是扩展的观察者模...

  • Java 注解

    1、Annotation的工作原理: JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型。该功能由...

网友评论

      本文标题:@EventListener注解的使用以及工作原理解读(观察者模

      本文链接:https://www.haomeiwen.com/subject/kttnqrtx.html