SpringBoot中资源初始化加载的几种方式
一、问题
在平时的业务模块开发过程中,难免会需要做一些全局的任务、缓存、线程等等的初始化工作,那么如何解决这个问题呢?方法有多种,但具体又要怎么选择呢?
二、资源初始化
1、既然要做资源的初始化,那么就需要了解一下springboot启动过程(这里大体说下启动过程,详细:https://www.cnblogs.com/dennyzhangdd/p/8028950.html)

按照前面的分析,Spring-boot容器启动流程总体可划分为2部分:
- 执行注解:扫描指定范围下的bean、载入自动配置类对应的bean加载到IOC容器。
- man方法中具体SpringAppliocation.run(),全流程贯穿SpringApplicationEvent(经典的spring事件驱动模型),有6个子类:
- ApplicationFailedEvent.class
- ApplicationPreparedEvent.class
- ApplicationReadyEvent.class
- ApplicationStartedEvent.class
- ApplicationStartingEvent.class
- SpringApplicationEvent.class
2、CommandLineRunner和ApplicationRunner
由上可知,我们只要实现这两个中的任何一个接口便可以完成我们的资源初始化任务,可以看到它们的加载是在容器完全启动之前。它两的区别是:前者的run方法参数是String...args,直接传入字符串,后者的参数是ApplicationArguments,对参数进行了封装。功能上是一样的。同时也可以使用 @Order注解来实现资源加载的先后顺序,值越小,优先级越高。实例如下:
@Component
@Order(1)
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("...init resources by implements CommandLineRunner");
}
}
@Component
@Order(2)
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
System.out.println("...init resources by implements ApplicationRunner");
}
}
3、@PostConstruct
在具体Bean的实例化过程中执行,@PostConstruct注解的方法,会在构造方法之后执行,顺序为Constructor > @Autowired > @PostConstruct > 静态方法,所以这个注解就避免了一些需要在构造方法里使用依赖组件的尴尬(与之对应的还有@PreDestroy,在对象消亡之前执行,原理差不多)。使用特点如下:
- 只有一个非静态方法能使用此注解
- 被注解的方法不得有任何参数
- 被注解的方法返回值必须为void
- 被注解方法不得抛出已检查异常
此方法只会被执行一次
@Component
public Class AAA {
@Autowired
private BBB b; public AAA() {
System.out.println("此时b还未被注入: b = " + b);
}
@PostConstruct
private void init() {
System.out.println("此时b已经被注入: b = " + b);
}
}
4、InitializingBean
InitializingBean 是 Spring 提供的一个接口,只包含一个方法 afterPropertiesSet()。凡是实现了该接口的类,当其对应的 Bean 交由 Spring 管理后,当其必要的属性全部设置完成后,Spring 会调用该 Bean 的 afterPropertiesSet()。在Bean在实例化的过程中执执行顺序为:Constructor > @PostConstruct > InitializingBean > init-method
public class InitSequenceBean implements InitializingBean {
public InitSequenceBean() {
System.out.println("InitSequenceBean: constructor");
}
@PostConstruct
public void postConstruct() {
System.out.println("InitSequenceBean: postConstruct");
}
public void initMethod() {
System.out.println("InitSequenceBean: init-method");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitSequenceBean: afterPropertiesSet");
}
}
5、ApplicationListener
ApplicationListener 就是spring的监听器,能够用来监听事件,典型的观察者模式。如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发。这种事件机制都必须需要程序显示的触发。其中spring有一些内置的事件,当完成某种操作时会发出某些事件动作。比如监听ContextRefreshedEvent事件,当所有的bean都初始化完成并被成功装载后会触发该事件,实现ApplicationListener接口可以收到监听动作,然后可以写自己的逻辑。同样事件可以自定义、监听也可以自定义,完全根据自己的业务逻辑来处理。所以也能做到资源的初始化加载!
@Component
public class DataSourceInitListener implements ApplicationListener<ContextRefreshedEvent> {//ContextRefreshedEvent为启动事件
private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceInitListener.class);
@Autowired
private SystemConfigService systemConfigService;
@Autowired
private ItemService itemService;
@Autowired
private SystemResultService systemResultService;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if(event.getApplicationContext().getParent() == null) {//判断是否执行过,执行过则不再执行
LOGGER.info("初始化systemConfig数据");
systemConfigService.initConfig();
LOGGER.info("初始化返回消息数据");
systemResultService.initResult();
LOGGER.info("系统初始化结束...........");
}
}
}
SpringBoot中资源初始化加载的几种方式的更多相关文章
- SpringBoot中资源初始化加载的几种方式(看这一片就够了)
一.问题 在平时的业务模块开发过程中,难免会需要做一些全局的任务.缓存.线程等等的初始化工作,那么如何解决这个问题呢?方法有多种,但具体又要怎么选择呢? 二.资源初始化 1.既然要做资源的初始化,那么 ...
- Unity中资源动态加载的几种方式比较
http://blog.csdn.net/leonwei/article/details/18406103 初学Unity的过程中,会发现打包发布程序后,unity会自动将场景需要引用到的资源打包到安 ...
- 如果你还不知道如何控制springboot中bean的加载顺序,那你一定要看此篇
1.为什么需要控制加载顺序 springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题.在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功 ...
- 点评js异步加载的4种方式
主要介绍了点评js异步加载的4种方式,帮助大家更全面的了解js异步加载方式,感兴趣的小伙伴们可以参考一下 js异步加载的4种方式,点评开始. <!DOCTYPE html> <htm ...
- route按需加载的3种方式:vue异步组件、es提案的import()、webpack的require.ensure()
1. vue异步组件技术 vue-router配置路由,使用vue的异步组件技术,可以实现按需加载. 但是,这种情况下一个组件生成一个js文件.举例如下: { path: '/promisedemo' ...
- HBase协处理器加载的三种方式
本文主要给大家罗列了HBase协处理器加载的三种方式:Shell加载(动态).Api加载(动态).配置文件加载(静态).其中静态加载方式需要重启HBase. 我们假设我们已经有一个现成的需要加载的协处 ...
- Spring中资源的加载原来是这么一回事啊!
1. 简介 在JDK中 java.net.URL 适用于加载资源的类,但是 URL 的实现类都是访问网络资源的,并没有可以从类路径或者相对路径获取文件及 ServletContext , 虽然可以通过 ...
- APP中数据加载的6种方式-b
我们看到的APP,往往有着华丽的启动界面,然后就是漫长的数据加载等待,甚至在无网络的时候,整个处于不可用状态.那么我们怎么处理好界面交互中的加载设计,保证体验无缝衔接,保证用户没有漫长的等待感,而可以 ...
- Flask程序相关配置加载的三种方式
方式一:从对象中加载配置 1.定义配置类,在配置类中添加相应的配置 2.通过app.config.from_object(配置类)进行加载 代码如下: from flask import Flask ...
随机推荐
- Vue知识整理11:列表渲染(v-for来实现)
简单的v-for结构显示迭代数据 通过value别名 显示下面各个属性值 通过index 和key获取同类数组索引,或者不同属性的key属性名
- webpack中的 chunk,module,bundle的区别,以及hidden modules是什么
hidden modules是什么: chunk,module,bundle的区别 总结: module是指任意的文件模块,等价于commonjs中的模块 chunks是webpack处理过程中被分组 ...
- k8s集群上线web静态网站
环境准备 一台部署节点,一台master节点,还有两台节点node1,node2 完好的k8s集群环境 思路1: 在node1和node2节点上通过宿主机与容器之间目录映射和端口映射上线静态网站(或动 ...
- node.js ffmpeg-concat 命令行形式处理多个视频的过度效果
ffmpeg-concat 是利用 gl-transitions 处理多个视频的过度效果.详细说明参见 https://github.com/transitive-bullshit/ffmpeg-co ...
- C# 获取当前网页HTML
//引用COM组件 //Microsoft HTML Object Library //Microsoft Internet Controls SHDocVw.ShellWindows shellWi ...
- elasticsearch7.0安装及配置优化
简单讲ES开箱即用,不用任何配置也能玩转搜索引擎:以下内容是根据易企秀线上实际使用场景进行的安装和配置,支持冷热数据分离 1.安装 Linux 环境下载安装包 curl -L -O https://a ...
- virtualbox压缩虚拟机硬盘文件vhd
命令如下: VBoxManage modifyhd D:\pc1\pc1.vhd --compact 当提示以下内容时,将整个虚拟机文件夹拷贝盘符根目录下,将[D:\pc1\pc1.vhd]改为相应 ...
- 【SD系列】SAP SD凭证处理被批次处理冻结
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[SD系列]SAP SD凭证处理被批次处理冻结 ...
- 应用安全 - Web框架 - Apache Solr - 漏洞汇总
CVE-2019-12409 Date: // 类型: 配置不当导致远程代码执行 前置条件: 影响范围: Solr and for Linux Solr下载:https://www.apache.or ...
- spring(二)
什么是AOP 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP(面向对 ...