springboot实战原理(10)--配置事件监听的4种方式和原理

简介: springboot实战原理(10)--配置事件监听的4种方式和原理

目录:


1dc618a0ed9580ce8bfa6facb208c08f.png


一、配置监听器的步骤:


1.自定义事件,一般是继承ApplicationEvent抽象类

2定义事件监听器,一般是实现ApplicationListener的接口

3.启动时候,需要把监听器加入到spring容器中

4.发布事件,使用ApplicationEventPublisher.publishEvent 发布事件


二、配置监听器:4种方式:


①SpringApplication…addListeners增加


例子:

//定义事件
//定义事件
public class MyAplicationEvent extends ApplicationEvent {
    private static final long serialVersionUID = 1L;
    public MyAplicationEvent(Object source) {
        super(source);
    }
}


//监听器
public class MyApplicationListener implements ApplicationListener<MyAplicationEvent> {
    @Override
    public void onApplicationEvent(MyAplicationEvent event) {
        System.out.println("接受到事件============"+ event.getClass());
    }
}


//在启动入口中:通过addListeners增加添加到spring容器和发布事件
@SpringBootApplication
public class Demo7Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Demo7Application.class);
        //addListeners增加
        app.addListeners(new MyApplicationListener());
        ConfigurableApplicationContext context = app.run(args);
        //发布事件
        context.publishEvent(new MyAplicationEvent(new Object()));
        context.close();
//        context.stop();
    }
}


运行结果:


5d4c6812c8535adbb050f4ddf2e1bce8.png

显示监听器已经注入。


② 使用@Component 把监听器纳入到spring容器中管理


修改刚才的代码:我们在监听器上加上@Component


//监听器
@Component
public class MyApplicationListener implements ApplicationListener<MyAplicationEvent> {
    @Override
    public void onApplicationEvent(MyAplicationEvent event) {
        System.out.println("接受到事件============"+ event.getClass());
    }
}


入口函数删除 addListener


@SpringBootApplication

public class Demo7Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Demo7Application.class);
        ConfigurableApplicationContext context = app.run(args);
        context.publishEvent(new MyAplicationEvent(new Object()));
        context.close();
//        context.stop();
    }
}


重新运行代码:

1dc618a0ed9580ce8bfa6facb208c08f.png

也说明,监听器生效了。


③ application.properties中配置context.listener.classes属性


配置如下: context.listener.classes=com.springboot.demo7.MyApplicationListener

5d4c6812c8535adbb050f4ddf2e1bce8.png


入口函数不变,继续运行:


@SpringBootApplication
public class Demo7Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Demo7Application.class);
        ConfigurableApplicationContext context = app.run(args);
        context.publishEvent(new MyAplicationEvent(new Object()));
        context.close();
//        context.stop();
    }
}


同样,监听器生效:


1dc618a0ed9580ce8bfa6facb208c08f.png


④使用注解 @EventListener


我们定义一个MyEventHandle监听器处理类, 使用注解 @EventListener,在方法上面加入@EventListener注解,且该类需要纳入到spring容器中管理。

看代码:


@Component
public class MyEventHandle {
    /*
     * 任意参数
     * 所有,该参数事件,或者其子事件都可以接收到
     * @param event  任意参数
     */
    @EventListener
    public void onApplicationEvent(MyAplicationEvent event) {
        System.out.println("接受到事件============"+ event.getClass());
    }
}


运行:


@SpringBootApplication
public class Demo7Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Demo7Application.class);
        ConfigurableApplicationContext context = app.run(args);
        context.publishEvent(new MyAplicationEvent(new Object()));
        context.close();
//        context.stop();
    }
}


5d4c6812c8535adbb050f4ddf2e1bce8.png

5d4c6812c8535adbb050f4ddf2e1bce8.png

依然注入进来了。


这里可以修改

46a9d80a6e05e4e3b19d57a0ee70bcdf.png


如果改成Object,就表示任意参数,所有,该参数事件,或者其子事件都可以接收到。


@Component
public class MyEventHandle {
    /*
     * 任意参数
     * 所有,该参数事件,或者其子事件都可以接收到
     * @param event  任意参数
     */
    @EventListener
    public void onApplicationEvent(Object event) {
        System.out.println("接受到事件============"+ event.getClass());
    }
 }


运行:


@SpringBootApplication
public class Demo7Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Demo7Application.class);
        ConfigurableApplicationContext context = app.run(args);
        context.publishEvent(new MyAplicationEvent(new Object()));
        context.close();
//        context.stop();
    }
}

1dc618a0ed9580ce8bfa6facb208c08f.png

可以看到,不过有我们自定义的事件,spring默认注入的事件都打印出来了。


三、原理


第一二种方式都是启动时候,把监听器加入到spring容器中,ConfigurableApplicationContext拿到这个对象再发布就可使用监听器了。

第三四中最终也是吧监听器ConfigurableApplicationContext,只不过实现有了2个特别的类:


①context.listener.classes配置原理之DelegatingApplicationListener:


看下源码


1dc618a0ed9580ce8bfa6facb208c08f.png

5d4c6812c8535adbb050f4ddf2e1bce8.png46a9d80a6e05e4e3b19d57a0ee70bcdf.png


我们可以看到,这个类是读取了配置的属性context.listener.classes,加入到监听器列表并序好给我们的spring容器。


② 注解@EventListener配置原理之 EventListenerMethodProcessor


看名字就知道EventListenerMethodProcessor这个是个后置处理器:

看下源码:

66ba272a0bfc97be54a5fa679e3d5482.png


afterSingletonsInstantiated方法调用了processBean方法:

processBean方法获取所有的@EventListener的注解:

1dc618a0ed9580ce8bfa6facb208c08f.png

该方法有这些注解的类加入到了context中,Springboot就可以使用了。

5d4c6812c8535adbb050f4ddf2e1bce8.png


四、spring和springboot默认自定义的事件查看


他们都在context包下:


看下springboot下的很多默认的事件和监听器

46a9d80a6e05e4e3b19d57a0ee70bcdf.png


看下spring5下的很多默认的事件和监听器:


66ba272a0bfc97be54a5fa679e3d5482.png


五、测试下默认的监听器:


我们测试下spring提供的:

1dc618a0ed9580ce8bfa6facb208c08f.png


我们使用第4种方式测试下:


@Component
public class MyEventHandle {
    @EventListener
    public void event2(ContextStoppedEvent event) {
        System.out.println("应用停止事件============"+ event.getClass());
    }
}


@SpringBootApplication
public class Demo7Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Demo7Application.class);
        ConfigurableApplicationContext context = app.run(args);
        context.stop();
    }
}


看下打印结果:

1dc618a0ed9580ce8bfa6facb208c08f.png

说明这个应用关闭的事件触发了。


总结:本文章主要讲了springboot配置监听器的步骤方式,原理和自带的事件等。


相关文章
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
6天前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
18 0
|
7天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
27 0
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
42 4
|
1月前
|
Java 数据库连接 Maven
springBoot:项目建立&配置修改&yaml的使用&resource 文件夹(二)
本文档介绍了如何创建一个基于Maven的项目,并配置阿里云仓库、数据库连接、端口号、自定义启动横幅及多环境配置等。同时,详细说明了如何使用YAML格式进行配置,以及如何处理静态资源和模板文件。文档还涵盖了Spring Boot项目的`application.properties`和`application.yaml`文件的配置方法,包括设置数据库驱动、URL、用户名、密码等关键信息,以及如何通过配置文件管理不同环境下的应用设置。
104 1
|
1月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
36 0
|
12天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
25 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
10天前
|
Java Spring
SpringBoot自动装配的原理
在Spring Boot项目中,启动引导类通常使用`@SpringBootApplication`注解。该注解集成了`@SpringBootConfiguration`、`@ComponentScan`和`@EnableAutoConfiguration`三个注解,分别用于标记配置类、开启组件扫描和启用自动配置。
49 17
|
10天前
|
Java 数据库连接
SpringBoot配置多数据源实战
第四届光学与机器视觉国际学术会议(ICOMV 2025) 2025 4th International Conference on Optics and Machine Vision
38 8
|
8天前
|
Java 数据库连接 数据库
springboot启动配置文件-bootstrap.yml常用基本配置
以上是一些常用的基本配置项,在实际应用中可能会根据需求有所变化。通过合理配置 `bootstrap.yml`文件,可以确保应用程序在启动阶段加载正确的配置,并顺利启动运行。
15 2