2021-01-11

博客园Logo
首页
新闻
博问
专区
闪存
班级
代码改变世界
搜索
注册
登录
返回主页丰极内心纯洁的人前途无量!
博客园首页新随笔联系管理订阅订阅随笔 - 24 文章 - 0 评论 - 21
springboot源码解析-管中窥豹系列之Runner(三)
一、前言
Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去。
我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot源码管中窥豹系列。
简介

二、Runner
假如我们想在springboot项目启动完成之后,做点什么,我们应该怎么办呢?
注意我们可以写在bean的初始化方法里面(我们后面讲),但是我们要用到其它已经加载了的bean的能力,又怎么办呢?
当然加顺序,加依赖也能解决,就是麻烦
这一节我们讨论一下springboot项目的Runner,Runner是在spring加载完毕执行的,springboot有两种Runner:

ApplicationRunner
CommandLineRunner
@FunctionalInterface
public interface ApplicationRunner {

void run(ApplicationArguments args) throws Exception;

}

@FunctionalInterface
public interface CommandLineRunner {

void run(String... args) throws Exception;

}

两种除了参数不同,其它没区别
ApplicationArguments是对传参数组的封装,本质也没区别
只有执行顺序上有区别,下面源码会看到
三、用法
实现接口就可以了

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class HelloRunner implements ApplicationRunner {

@Override
public void run(ApplicationArguments args) throws Exception {
    System.out.println("hello runner");
}

}
因为这时候spring已经加载完毕,你可以引入其它bean
启动项目,你会发现在日志最下方打印了上面的话
四、源码解读
我们直接找SpringApplication类的run方法,想看整体框架的去第一节。

public ConfigurableApplicationContext run(String… args) {

...

try {
    
    ...

    callRunners(context, applicationArguments);
    
    ...

}
catch (Throwable ex) {
    
    ...

}

...

return context;

}
我们直接定位到callRunners方法。

private void callRunners(ApplicationContext context, ApplicationArguments args) {
List runners = new ArrayList<>();
// (1) 找到ApplicationRunner的实现类,加到list里面
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
// (2) 找到CommandLineRunner的实现类,加到list里面
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
// (3) 排序
AnnotationAwareOrderComparator.sort(runners);
// (4) 钩子回调
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}
总共分四步:

(1) 找到ApplicationRunner的实现类,加到list里面

(2) 找到CommandLineRunner的实现类,加到list里面

(3) 排序

(4) 钩子回调

我们看一下canllRunner

private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
try {
(runner).run(args);
}
catch (Exception ex) {
throw new IllegalStateException(“Failed to execute ApplicationRunner”, ex);
}
}

private void callRunner(CommandLineRunner runner, ApplicationArguments args) {
try {
(runner).run(args.getSourceArgs());
}
catch (Exception ex) {
throw new IllegalStateException(“Failed to execute CommandLineRunner”, ex);
}
}
除了传参方式,都一样。
上面说的执行顺序问题,是先添加的ApplicationRunner,如果只有@Component,先执行ApplicationRunner
欢迎关注公众号:丰极,更多技术学习分享。

标签: 源码, springboot, Java
好文要顶 关注我 收藏该文
丰极
关注 - 0
粉丝 - 14
+加关注
00
« 上一篇: springboot源码解析-管中窥豹系列之项目类型(二)
posted @ 2021-01-11 09:54 丰极 阅读(94) 评论(0) 编辑 收藏
刷新评论刷新页面返回顶部
登录后才能发表评论,立即 登录 或 注册, 访问 网站首页
【推荐】阿里出品,对标P7!限时免费,七天深入MySQL实战营报名开启
【推荐】大型组态、工控、仿真、CADGIS 50万行VC++源码免费下载
【推荐】AWS携手博客园为开发者送福利,注册立享12个月免费套餐
【推荐】第一个NoSQL数据库,在大规模和一致性之间找到了平衡
【推荐】七牛云新老用户同享 1 分钱抢 CDN 1TB流量大礼包!
【推荐】了不起的开发者,挡不住的华为,园子里的品牌专区
【推荐】未知数的距离,毫秒间的传递,声网与你实时互动

相关博文:
· GitLabRunner安装与注册
· SpringBoot
· SpringBoot
· SpringBoot
· Springboot
» 更多推荐…

最新 IT 新闻:
· 为什么贝壳、百度、蔚来值得放在一起研究?
· 能刷好评也能删差评 大众点评变味了?
· 前懂球帝CTO许立强日前正式加入字节跳动 曾担任百度主任架构师
· 82万的新车一月连撞两车 女司机称刹车失灵!特斯拉:你去告我们
· 比宝马5系贵2万多!秦力洪:蔚来ET7订单达预期 不会降价
» 更多新闻…
昵称: 丰极
园龄: 2年6个月
粉丝: 14
关注: 0
+加关注
< 2021年1月 >
日 一 二 三 四 五 六
27 28 29 30 31 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6
搜索

My Tags
Java(18)
springboot(5)
源码(3)
算法(2)
spring(2)
网盘(1)
性能调优(1)
中间件(1)
springdatajpa(1)
thymleaf(1)
更多
随笔档案
2021年1月(3)
2020年12月(1)
2020年11月(2)
2020年10月(1)
2020年7月(4)
2018年12月(1)
2018年10月(3)
2018年9月(4)
2018年8月(1)
2018年7月(3)
2018年6月(1)
Recent Comments

  1. Re:springboot源码解析-管中窥豹系列之总体结构(一)
    期待 继续更新

–winds_随风
2. Re:Java性能调优
java性能调优实战资料分享滴我1160405674,这个是群

–图灵学院在线
3. Re:从零开始搭建SpringBoot项目
@LSX少年 刚接触的SpringBoot,跪求一份源码,可以嘛?1774231637@qq.com 关注微信公众号:丰极,回复:springboot1,有项目的github地址。…
–丰极
4. Re:从零开始搭建SpringBoot项目
刚接触的SpringBoot,跪求一份源码,可以嘛?1774231637@qq.com

–LSX少年
5. Re:从零开始搭建SpringBoot项目
统一回复。
关注微信公众号:丰极,回复:springboot1,有项目的github地址。

–丰极
Top Posts

  1. 从零开始搭建SpringBoot项目(72827)
  2. Java定时任务(49309)
  3. Java性能调优(3126)
  4. Springboot集成Swagger2(725)
  5. Java1.8的HashMap源码解析(559)
    推荐排行榜
  6. 从零开始搭建SpringBoot项目(8)
  7. Java定时任务(5)
  8. springboot源码解析-管中窥豹系列之总体结构(一)(2)
  9. Java1.7的HashMap源码分析-面试必备技能(1)
    Copyright © 2021 丰极
    Powered by .NET 5.0 on Kubernetes
以下是一个获取当前日期时间,并将它以“XXXX年XX月XX日 hh:mm:ss”的格式输出打印的示例代码: ```java import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; public class DateUtils { // 获取当前日期时间,并将它以“XXXX年XX月XX日 hh:mm:ss”的格式输出打印 public static void showCurrentDateTime() { DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); Date date = new Date(); String dateTime = dateFormat.format(date); System.out.println(dateTime); } // 计算并显示若干天后的日期值 public static void showDateAfterDays(String currentDate, int days) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { Date date = dateFormat.parse(currentDate); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DAY_OF_YEAR, days); Date newDate = calendar.getTime(); String newDateString = dateFormat.format(newDate); System.out.println(newDateString); } catch (ParseException e) { e.printStackTrace(); } } // 计算并显示两个日期之间相距的天数 public static void showDaysBetweenDates(String date1, String date2) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { Date startDate = dateFormat.parse(date1); Date endDate = dateFormat.parse(date2); long diff = endDate.getTime() - startDate.getTime(); long diffDays = diff / (24 * 60 * 60 * 1000); System.out.println(diffDays); } catch (ParseException e) { e.printStackTrace(); } } } ``` 使用示例: ```java public static void main(String[] args) { // 获取当前日期时间,并将它以“XXXX年XX月XX日 hh:mm:ss”的格式输出打印 DateUtils.showCurrentDateTime(); // 计算并显示若干天后的日期值 DateUtils.showDateAfterDays("2021-01-01", 10); // 计算并显示两个日期之间相距的天数 DateUtils.showDaysBetweenDates("2021-01-01", "2021-01-11"); } ``` 输出结果: ``` 2021年05月01日 15:23:45 2021-01-11 10 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值