SpringBoot 系列之监听器

在这里插入图片描述
Spring Boot 监听器是Spring框架中一个重要的组成部分,它允许你在Spring应用程序的生命周期中的特定时刻执行某些操作。在Spring Boot中,监听器主要用于响应应用程序中发生的事件。这些事件可以是应用程序的启动、关闭,或者是Spring上下文中的bean的创建和销毁等。

1. 监听器实现方式

Spring Boot提供了多种方式来实现监听器:

1.1 实现ApplicationListener接口

通过实现ApplicationListener接口来创建一个监听器。这个接口要求你实现一个onApplicationEvent方法,该方法会在事件发生时被调用。

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 你的逻辑
    }
}

1.2 使用@EventListener注解

在方法上使用@EventListener注解来创建一个监听器,这种方法比实现接口更加简洁。

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
public class MyEventListener {

    @EventListener
    public void handleContextRefreshedEvent(ContextRefreshedEvent event) {
        // 你的逻辑
    }
}

2. SpringBoot 默认监听器

监听器名称监听的事件描述
ApplicationStartingListenerApplicationStartingEvent在应用程序启动初期,用于日志和注册监听器。
ConfigurationPropertyBindingListenerApplicationEnvironmentPreparedEvent在环境准备完成后,绑定配置属性。
ConfigFileApplicationListenerApplicationEnvironmentPreparedEvent, ApplicationPreparedEvent加载配置文件并设置环境属性。
AnsiOutputApplicationListenerApplicationStartingEvent, ApplicationEnvironmentPreparedEvent根据环境配置ANSI输出。
LoggingApplicationListenerApplicationStartingEvent, ApplicationEnvironmentPreparedEvent, ApplicationPreparedEvent, ApplicationFailedEvent配置日志系统。
ClasspathLoggingApplicationListenerApplicationStartingEvent, ApplicationEnvironmentPreparedEvent记录类路径下的资源。
FileEncodingApplicationListenerApplicationEnvironmentPreparedEvent检查文件编码。
DelegatingApplicationListenerApplicationEvent将事件委托给其他监听器。
ContextIdApplicationContextInitializerApplicationPreparedEvent设置ApplicationContext的ID。
SharedMetadataReaderFactoryContextInitializerApplicationPreparedEvent初始化共享的元数据读取工厂。
ServerPortInfoApplicationContextInitializerApplicationPreparedEvent记录服务端口信息。
ConditionEvaluationReportLoggingListenerApplicationPreparedEvent, ApplicationFailedEvent记录条件评估报告。
ResetMocksApplicationListenerBeforeTestClassEvent, AfterTestClassEvent测试相关,重置Mock对象。
ParentContextCloserApplicationListenerApplicationEvent确保父级上下文在子级上下文之后关闭。
ClearCachesApplicationListenerContextClosedEvent清理缓存。
FileWatcherConfigurationApplicationListenerApplicationEvent监控配置文件的变化。

3. 原理解析

SpringApplication的构造方法中会加载所有声明在spring.factories中的监听器。
在这里插入图片描述
在这里插入图片描述

3.1 初始化监听器

在 SpringApplication 类的构造方法中,初始化了所有的监听器。
SpringBoot 的启动类调用 SpringApplication 的 run 方法,run 方法中new 了一个 SpringApplication 对象,我们看看在 SpringApplication 的构造方法中都处理了上面逻辑
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 实例化监听器

在这里插入图片描述
在这段代码中,前面SpringFactoriesLoader.forDefaultResourceLocation(getClassLoader())是加载 spring.factories 中的监听器,而后面的 load 方法则是实例化加载的监听器了。
在这里插入图片描述
在这里插入图片描述

3.3 发布事件

在 SpringApplication 的 run 方法中,我们可以看到很多的事件发布
在这里插入图片描述
我们随便看个,其他的都类似,比如我们看服务启动监听器:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由此我们可以看到,其实最后就是调用到了,监听器的onApplicationEvent方法。

4. 自定义事件

理论的学完了,我们看下在日常开发过程中,如何使用事件呢?
可以从三个角度来看:监听所有事件、监听特定事件、自定义监听事件

4.1 监听所有事件

  1. 实现ApplicationListener接口,在泛型中指定要监听的事件。若指定的是ApplicationEvent则监听所有的事件
  2. 要在 spring.facotries 中导入自定义的事件监听器
public class MyApplicationAllEventListener implements ApplicationListener<ApplicationEvent> {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("MyApplicationAllEventListener监听到事件:" + event);
    }
}
org.springframework.context.ApplicationListener=\
com.michael.demo.event.MyApplicationAllEventListener

结果:
在这里插入图片描述

4.2 监听特定事件

监听特定事件同监听所有事件,只需要将泛型指定为具体的事件即可
如监听容器启动事件

public class MyApplicationAllEventListener implements ApplicationListener<ApplicationStartingEvent> {
    @Override
    public void onApplicationEvent(ApplicationStartingEvent event) {
        System.out.println("MyApplicationAllEventListener监听到事件:" + event);
    }
    
}

4.3 自定义监听事件

接下来我们使用自定义的监听器监听自定义的事件
首先我们定义一个事件,需要继承ApplicationEvent

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

然后定义自定义监听器

public class MyApplicationAllEventListener implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("MyApplicationAllEventListener监听到事件:" + event);
    }

}

最后也是需要在 spring.factories 中注册的。

发布自定义事件

事件的发布可以使用ApplicationContext类中的publishEvent 方法

@Resource
private ApplicationContext ac;

public void publishEvent(){
	ac.publishEvent(new MyEvent(new Object));
}

到此为止,我们搞清楚了 SpringBoot 中的事件和监听器,并且可以自定义事件和监听器了,后续项目中在合适的场景下就可以使用了!!!

  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这篇文章介绍了如何通过开启 MySQL 的 Binlog 日志,并利用 Kafka 实时同步 MySQL 数据到 SQL Server 数据库中。 首先,需要在 MySQL 中开启 Binlog 日志。可以通过修改 MySQL 配置文件(my.cnf 或 my.ini)来开启 Binlog 日志: ``` [mysqld] log-bin=mysql-bin binlog-format=row server-id=1 ``` 其中,`log-bin` 指定了 Binlog 文件的名称前缀,`binlog-format` 指定 Binlog 记录的格式为行格式,`server-id` 指定了 MySQL 实例的唯一标识。 接下来,需要创建一个 Kafka 主题,并启动一个 Kafka 生产者,将 MySQL Binlog 数据写入 Kafka 主题: ```java import com.github.shyiko.mysql.binlog.BinaryLogClient; import com.github.shyiko.mysql.binlog.event.*; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerRecord; public class BinlogProducer { private final BinaryLogClient client; private final KafkaProducer<String, String> producer; private final String topic; public BinlogProducer(String hostname, int port, String username, String password, String topic) { this.client = new BinaryLogClient(hostname, port, username, password); this.producer = new KafkaProducer<>(getKafkaConfig()); this.topic = topic; } public void start() throws Exception { client.registerEventListener(event -> { EventData data = event.getData(); if (data instanceof WriteRowsEventData) { WriteRowsEventData eventData = (WriteRowsEventData) data; for (Serializable[] row : eventData.getRows()) { String message = "INSERT INTO " + eventData.getTableId() + " VALUES " + Arrays.toString(row); producer.send(new ProducerRecord<>(topic, message)); } } else if (data instanceof UpdateRowsEventData) { UpdateRowsEventData eventData = (UpdateRowsEventData) data; for (Map.Entry<Serializable[], Serializable[]> row : eventData.getRows()) { String message = "UPDATE " + eventData.getTableId() + " SET " + Arrays.toString(row.getValue()) + " WHERE " + Arrays.toString(row.getKey()); producer.send(new ProducerRecord<>(topic, message)); } } else if (data instanceof DeleteRowsEventData) { DeleteRowsEventData eventData = (DeleteRowsEventData) data; for (Serializable[] row : eventData.getRows()) { String message = "DELETE FROM " + eventData.getTableId() + " WHERE " + Arrays.toString(row); producer.send(new ProducerRecord<>(topic, message)); } } }); client.connect(); } public void stop() throws Exception { client.disconnect(); producer.close(); } private Map<String, Object> getKafkaConfig() { Map<String, Object> config = new HashMap<>(); config.put("bootstrap.servers", "localhost:9092"); config.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); config.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); return config; } } ``` 上述代码中,`BinaryLogClient` 是一个 MySQL Binlog 客户端,可以用来监听 MySQL 数据库的 Binlog 事件。在 `start()` 方法中,我们通过注册事件监听器来捕获 Binlog 事件,然后将事件数据写入 Kafka 主题。需要注意的是,对于不同类型的 Binlog 事件(如插入、更新、删除等),需要分别处理,并将事件数据转换成插入、更新、删除语句,然后写入 Kafka 主题中。 最后,需要启动一个 Kafka 消费者,从 Kafka 主题中读取 Binlog 数据,并写入 SQL Server 数据库中: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Component; @Component public class BinlogConsumer { private final JdbcTemplate jdbcTemplate; @Autowired public BinlogConsumer(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @KafkaListener(topics = "binlog") public void onMessage(String message) { jdbcTemplate.execute(message); } } ``` 上述代码中,`BinlogConsumer` 是一个 Kafka 消费者,使用 `@KafkaListener` 注解来监听 Kafka 主题中的消息。当收到消息时,直接执行消息中的 SQL 语句,将数据写入 SQL Server 数据库中。 通过上述方式,就可以实现 MySQL 数据库和 SQL Server 数据库之间的实时数据同步了。需要注意的是,由于 Binlog 日志是一个增量日志,因此在启动同步任务时,需要首先将 MySQL 数据库中的数据全量复制到 SQL Server 数据库中,然后再开启 Binlog 日志,以保证数据的完整性和一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值