强大的Spring Boot启动监听器事件-初始化系统账号密码

Posted DT辰白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了强大的Spring Boot启动监听器事件-初始化系统账号密码相关的知识,希望对你有一定的参考价值。


前言

在SpringBoot项目启动的过程中,监听器在不同阶段都会监听相应的事件,我们可以通过监听相应的事件,处理一些任务,比如在启动成功之后初始化数据库,免去建表的操作,还有初始化管理员账号密码,初始化缓存、特定任务的注册等操作。

事件就是Spring Boot启动过程的状态描述,在启动Spring Boot时所发生的事件一般指:

开始启动事件、环境准备完成事件、上下文准备完成事件 、上下文加载完成事件 、应用启动完成事件


一、SpringApplicationEvents 事件类型

1.1 ApplicationStartingEvent

这个事件在 Spring Boot 应用运行开始时,且进行任何处理之前发送(除了监听器和初始化器注册之外)。

1.2 ApplicationEnvironmentPreparedEvent

这个事件在当已知要在上下文中使用 Spring 环境(Environment)时,在 Spring 上下文(context)创建之前发送。

1.3 ApplicationContextInitializedEvent

这个事件在当 Spring 应用上下文(ApplicationContext)准备好了,并且应用初始化器(ApplicationContextInitializers)已经被调用,在bean 的定义(bean definitions)被加载之前发送。

1.4 ApplicationPreparedEvent

这个事件是在 Spring 上下文(context)刷新之前,且在 bean 的定义(bean definitions)被加载之后发送。

1.5 ApplicationStartedEvent

这个事件是在 Spring 上下文(context)刷新之后,且在 application/ command-line runners被调用之前发送。

1.6 AvailabilityChangeEvent

这个事件紧随上个事件之后发送,状态:ReadinessState.CORRECT,表示应用已处于活动状态。

1.7 ApplicationReadyEvent

这个事件在任何 application/ command-line runners 调用之后发送。

1.8 AvailabilityChangeEvent

这个事件紧随上个事件之后发送,状态:ReadinessState.ACCEPTING_TRAFFIC,表示应用可以开始准备接收请求了。

1.9 ApplicationFailedEvent

这个事件在应用启动异常时进行发送。

二、如何启动监听器事件

2.1 原理概念

上面介绍了那么多Spring Boot启动监听器事件,该如何实现呢?这里就涉及到一个概念:观察者模式

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

对于 Spring 容器的一些事件,可以监听并且触发相应的方法。通常的方法有 2 种,ApplicationListener 接口和@EventListener 注解。

2.2 实现ApplicationListener接口

ApplicationListener接口源码
通过阅读接口源码我们就知道了:需要实现ApplicationListener接口并实现onApplicationEvent方法。把需要处理的操作放在onApplicationEvent中进行处理,并且ApplicationListener是一个泛型继承了父类。

/**
 * @description: 通过ApplicationListener接口实现监听消息发送
 * @author: DT
 * @date: 2021/5/10 21:39
 * @version: v1.0
 */
@Component
public class MyApplicationEventListener implements ApplicationListener<ApplicationReadyEvent> {

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        System.out.println("ApplicationListener接口>>>"+applicationReadyEvent.toString());
    }
}

2.3 通过@EventListener注解

这种方式就特别简单了,只需要一个@EventListener注解即可。

@SpringBootApplication
public class JdbcApplication {

    public static void main(String[] args) {
        SpringApplication.run(JdbcApplication.class, args);
    }

    /**
     * 使用@EventListener注解,注册ApplicationReadyEvent
     * ApplicationReadyEvent:上下文已经准备完毕的时候触发
     */
    @EventListener
    public void deploymentVer(ApplicationReadyEvent event) {
        System.out.println("上下文已经准备完毕的时候触发>>>"+event.toString());
    }

}

在这里插入图片描述

三、案例演示

上面我们通过两种方式实现了Spring Boot启动监听器事件,下面我们来做一个简单基础的案列。

3.1 需求:项目启动、初始化系统登录的账号和密码。

3.1.1 pom.xml依赖

这里我们使用Jdbc来操作连接数据库,下面是pom.xml核心依赖代码:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

3.1.1 application.yml配置文件

server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://192.168.31.158:3306/testjdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.mysql.cj.jdbc.MysqlDataSource

3.1.2 t_user表结构

在这里插入图片描述

3.1.3 监听器

@EventListener
public void deploymentVer(ApplicationReadyEvent applicationReadyEvent) {
    System.out.println("系统初始化账号密码>>>"+applicationReadyEvent.toString());
    // 调用函数,设置系统初始化账号密码
    SystemInitUtils.initData();
}

3.1.4 SystemInitUtils.java

/**
 * @description: 系统初始化调用
 * @author: DT
 * @date: 2021/5/10 21:59
 * @version: v1.0
 */
public class SystemInitUtils {

    /**
     * 系统初始化账号密码
     */
    public static void initData() {
        // 获取jdbcTemplate对象
        JdbcTemplate jdbcTemplate = (JdbcTemplate)SpringUtils.getBean("jdbcTemplate");
        // 设置超级管理员账号
        long count = jdbcTemplate.queryForObject("select count(*) from t_user where username = 'admin'", Long.class);
        if(count == 0){
            Object[] args=new Object[]{"admin","123456",new Date(),new Date()};
            jdbcTemplate.update("insert into t_user(username,password,create_time,update_time) values (?,?,?,?)",args);
        }
    }
}

3.1.5 SpringUtils.java通用工具类

/**
 * @description: 从已有的spring上下文取得已实例化的bean
 * @author: DT
 * @date: 2021/5/10 22:03
 * @version: v1.0
 */
@Component
public class SpringUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringUtils.applicationContext = applicationContext;
    }

    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }
}

3.1.6 启动程序

在这里插入图片描述
到此完美收工,通过ApplicationReadyEvent监听器事件,我们做了一个案例。当然除了上面的两种方式外,我们也可以自定义监听事件,这里小编先不做讲解。

总结

在SpringBoot项目启动的过程中,监听器在不同阶段都会监听相应的事件,后面的文章我们会继续出一些干货,比如初始化数据库,不用再去导数据库,不用再去新建表字段,直接通过实体映射结合Spring Boot启动监听器事件生成表结构,这样的开发逼格是不是有提升了一个档次,敬请期待下篇。

以上是关于强大的Spring Boot启动监听器事件-初始化系统账号密码的主要内容,如果未能解决你的问题,请参考以下文章

头秃系列,二十三张图带你从源码分析Spring Boot 启动流程~

Spring Boot 启动事件和监听器,太强大了!

spring boot的spring.factories配置的不同类/以及加载时机

009-Spring Boot 事件监听

Spring Boot 整合监听器

spring boot实战(第二篇)事件监听