实战讲解SpringBoot启动时自动加载数据库数据到内存:通过回调方法自动运行Bean(图+文+源码)

1 缘起

在补充SpringCloud网关(Gateway)配置白名单相关知识过程中,
有两种实现方案:
(1)SpringBoot的启动配置文件application.yml进行配置;
(2)自动加载MySQL数据库中的白名单数据到内存(JVM)实现;
第一种方案,很简单,只需将白名单配置在启动文件中,SpringBoot启动时会自动加载,无需开发者操心,而,第二种方案,从MySQL自动加载数据到内存,则需要开发者自己实现,核心问题:SpringBoot启动时,自动运行配置的Bean,SpringBoot提供了两种实现方案,均是在启动SpringBoot时,通过回调的方式,运行Bean,更确切描述是:当依赖的Bean存在于SpringApplication中时,回调执行自定义的Bean,两种接口类:
(1)ApplicationRunner
(2)CommandLineRunner
Note:
执行结束后,SpringBoot完成启动,当然,这也带来一个问题,
如果自定义的Bean执行时间过长,SpringBoot应用在这个空窗期,是无法对外提供服务的。

2 Runner

SpringBoot提供了两个Runner接口类,自动回调执行Bean。

2.1 CommandLineRunner

由注释可知,CommandLineRuuner接口类用于执行某个已存在于SpringApplication的Bean,如果在同一个应用上下文中有多个需要CommandLineRunner执行的Bean,可通过Ordered接口或@Order注解配置执行顺序。
CommandLineRunner的回调方法run配置的参数为原生String,如果需要读取命令行中配置的参数,可以使用ApplicationRunner接口类。
在这里插入图片描述

2.2 ApplicationRunner

由注释可知,ApplicationRunner接口类用于执行某个已存在于SpringApplication的Bean,如果在同一个应用上下文中有多个需要CommandLineRunner执行的Bean,可通过Ordered接口或@Order注解配置执行顺序。
在这里插入图片描述

3 测试

SpringBoot启动时,从MySQL读取用户信息,读取结束,完成SpringBoot启动。

3.1 样例

package com.monkey.standalone.common.mybean;

import com.github.pagehelper.PageInfo;
import com.monkey.standalone.modules.user.service.IUserService;
import com.monkey.standalone.modules.user.vo.UserPageInputVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 回调执行Bean.
 *
 * @author xindaqi
 * @since 2022-11-19 21:59
 */
@Component
public class LoadDataBean implements ApplicationRunner, CommandLineRunner {

    private static final Logger logger = LoggerFactory.getLogger(LoadDataBean.class);

    @Resource
    IUserService userService;

    private UserPageInputVO userPageInputVO = new UserPageInputVO(1, 2);

    @Override
    public void run(ApplicationArguments args) throws Exception {
        PageInfo<BaseUserVO> userPage =  userService.queryUserByPage(userPageInputVO);
        logger.info(">>>>>>>>Application runner, user info:{}", userPage);
    }

    @Override
    public void run(String... args) throws Exception {
        PageInfo<BaseUserVO> userPage =  userService.queryUserByPage(userPageInputVO);
        logger.info(">>>>>>>>Command line runner, user info: {}", userPage);
    }
}

3.2 结果

启动SpringBoot过程中,执行ApplicationRuuner和CommandLineRunner回调方法run中的逻辑。
首先,执行的是ApplicationRunner的回调方法,结果如下图所示。
在这里插入图片描述
然后执行的是CommandLineRunner的回调方法,结果如下图所示。
最后,输出SpringBoot启动成功的日志,表明,当Runner接口的回调方法逻辑执行结束,
SpringBoot才会完成启动,上面提到的加载空窗期,SpringBoot应用无法对外提供服务,开发者需要以及实际情况调整加载的数据量。

在这里插入图片描述

4 小结

(1)SpringBoot启动过程中,通过回调方式执行Bean的两个接口类:ApplicationRunner和CommandLineRunner;
(2)ApplicationRunner回调方法可以获取输入的参数,CommandLineRunner中的回调方法使用原生字符串;
(3)ApplicationRunner和CommandLineRunner完成加载后才会完成SpringBoot启动,加载空窗期, SpringBoot应用无法对外提供服务。
Note:
感兴趣的可以学习其他的实现:@PostConstruct和InitializingBean,
参见文章:
https://blog.csdn.net/Xin_101/article/details/120062024

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天然玩家

坚持才能做到极致

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值