3 SpringBoot监听器

本文介绍了监听器的基本概念,包括事件源、监听器和响应行为。重点讲解了Spring Boot中的四种监听器,如CommandLineRunner、ApplicationRunner等。虽会介绍四个监听器的简单使用,但主要针对程序启动后的监听器。还给出简单案例,实现应用启动完成时初始化redis缓存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 监听器的基本概念

监听器就是监听某个对象的状态发生变化的组件,监听器的相关概念:

  • 事件源:被监听的对象
  • 监听器:用于监听事件源对象,事件源对象状态的变化都会触发监听器
  • 响应行为:监听器监听到事件源的状态变化时的响应

2 SpringBoot中的监听器

  • CommandLineRunner:应用程序启动完成后
  • ApplicationRunner:应用程序启动完成后
  • ApplicationContextInitializer:应用程序初始化之前
  • SpringApplicationRunListener:应用程序全阶段监听 

上述第四个监听器“应用程序全阶段监听”中的各个阶段如下:

  1. 应用程序开始启动--starting
  2. 环境准备完成--environmentPrepared
  3. spring容器准备完成--environmentPrepared
  4. spring容器加载完成--environmentPrepared
  5. 应用程序启动完成--started
  6. 应用程序开始运行--running
  7. 应用程序运行时抛出异常时调用--failed

上述4个监听器中,后两个监听器涉及到程序启动之前的监听,而我们这次主要针对程序启动之后的监听器展开学习。所以接下来虽然会介绍上述四个监听器的简单使用,但是只会针对前两个监听器进行实际案例的使用介绍。

监听器1:CommandLineRunner:应用程序启动完成后

/**
 * 监听,当前应用程序启动之后,做一些事情
 * 把所有的用户数据缓存到redis,而不是每次第一次点击才进行缓存
 */
@Component
public class My01CommandLineRunnerListener implements CommandLineRunner {

    /**
     * 当应用程序启动后,会执行run方法
     * 参数:主函数的参数列表
     */
    @Override
    public void run(String... args) throws Exception {
        System.out.println("当前应用程序已经启动完成,主函数参数:"+args);
    }
}

监听器2:ApplicationRunner:应用程序启动完成后

/**
 * 监听,当前应用程序启动之后,做一些事情
 * 把所有的用户数据缓存到redis,而不是每次第一次点击才进行缓存
 */
@Component
public class My02ApplicationRunListener implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("当前应用程序已经启动完成,主函数参数:"+args);
    }
}

监听器3:ApplicationContextInitializer:应用程序初始化之前

/**
 * 在spring容器初始化之前执行
 */
public class My03ApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("spring容器开始初始化");
    }
}

监听器4:SpringApplicationRunListener:应用程序全阶段监听 

/**
 * 应用程序启动全流程,监听器
 */
public class My04SpringApplicationRunListener implements SpringApplicationRunListener {
    public My04SpringApplicationRunListener(SpringApplication application, String[] args) {}


    @Override
    public void starting(){
        System.out.println("应用程序开始启动:starting");
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment){
        System.out.println("应用程序环境准备完成:environmentPrepared");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context){
        System.out.println("应用程序的spring容器准备完成:contextPrepared");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context){
        System.out.println("应用程序的spring容器装载完成:contextLoaded");
    }

    @Override
    public void started(ConfigurableApplicationContext context){
        System.out.println("应用程序的启动完成:started");
    }

    @Override
    public void running(ConfigurableApplicationContext context){
        System.out.println("应用程序正常运行:running");
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception){
        System.out.println("应用程序运行出错:failed");
    }
}

3 监听器简单案例

目标:当应用程序启动完成时,完成redis缓存的初始化。

步骤

  • 实现ApplicationRunner接口,重写run()方法
  • 注入UserService接口实现类(用来从Mysql中查询数据)及RedisTemplate对象(用来把数据存到redis)
  • 将用户数据存入redis缓存
/**
 * 初始化项目时,就查询所有用户数据到缓存中
 */

@Component
public class RedisCacheInitializerListener implements ApplicationRunner {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserService userService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        //拿到所有用户数据
        List<User> users = userService.findAll();
        //数据存入redis
        redisTemplate.boundValueOps(UserController.key).set(users);
        System.out.println("监听器初始化redis缓存成功");
    }
}
@RestController
public class UserController {
    @Autowired
    private UserService service;
    @Autowired
    private RedisTemplate redisTemplate;
    //缓存的为唯一标识:redis中的key值(全限定类名+方法名称),value是查询所有用户的结果
    public static final String key = UserService.class.getName()+".findAll";
    /**
     * 查询所有用户
     * @return
     */
    @RequestMapping("/user/findAll")
    private List<User> findAll(){
        /**
         * 首先从redis缓存中取数据:key,service接口的全限定名称+方法名称
         * 如果有返回给用户,如果没有从mysql查返回给用户并存到reids
         */
        //函数返回值,即用户信息
        List<User> users = null;
        //从redis取数据
        users = (List<User>) redisTemplate.boundValueOps(key).get();
        //如果没取到,就是从mysql查数据,并且保存一份到缓存,如果查到了就直接返回
        if(users==null){
            //缓存没数据,去mysql查,结果还是要存一份到redis(针对监听器,这个步骤其实没必要)
            users = service.findAll();
            redisTemplate.boundValueOps(key).set(users);
            System.out.println("从数据库取数据");
        }else {
            System.out.println("从redis缓存中取数据");
        }
        return users;
    }
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值