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 ...
随机推荐
- C#与Java覆盖问题
C#继承类中如含有相同的方法,避免冲突使用new关键字.在不同对象中分别对应该方法.若使用override关键字则,基类中的方法被覆盖. 如需调用非覆盖的则使用base关键字. Java中的继承类方法 ...
- 2018.03.26 Python-Pandas 字符串常用方法
import numpy as np import pandas as pd 1 #字符串常用方法 - strip s = pd.Series([' jack ','jill',' jease ',' ...
- C++/C# 转化 Marshal VS Ptr
Vidyo32.VidyoClientInEventLogin Login = new Vidyo32.VidyoClientInEventLogin(); Login.portalUri = thi ...
- TestNG+extentReports+log4j2 完善自动化测试框架——美观的报告和保留日志文件
1:导入Maven依赖<dependency> <groupId>com.aventstack</groupId> <artifactId>extent ...
- Python_ONLINE_习题集_1 递归
1.1 使用递归实现:计算某个数的阶乘 def func(x): if x == 2: return 2 else: return x*func(x-1) a = func(4) print(a) 2 ...
- 第四周预习作业and第五周作业
第四周预习作业 统计一行文本的单词个数 本题目要求编写程序统计一行字符中单词的个数.所谓"单词"是指连续不含空格的字符串,各单词之间用空格分隔,空格数可以是多个. 输入格式: 输入 ...
- [Web 前端] 024 js 的定时器及函数
1. Javascript 定时器 1.1 计时事件 设定一个间隔,时间到了后准时执行代码,此为"计时事件" 1.2 作用 1.制作动画 2.异步操作 1.3 定时器的类型及语法 ...
- SQL Server中的扩展事件学习系列
SQL Server 扩展事件(Extented Events)从入门到进阶(1)——从SQL Trace到Extented Events SQL Server 扩展事件(Extented Event ...
- linux服务器上安装mysql
mysql版本:mysql-5.6.44-linux-glibc2.12-x86_64.tar linux操作系统和版本信息: 1.检查linux服务器上是否已安全mysql [root@localh ...
- 各类最新Asp .Net Core 项目和示例源码
1.网站地址:http://www.freeboygirl.com2.网站Asp .Net Core 资料http://www.freeboygirl.com/blog/tag/asp%20net%2 ...