8、项目启动时,执行某个方法
很多时候我们都会碰到需要在程序启动时去执行的方法,比如说去读取某个配置,预加载缓存,定时任务的初始化等。这里给出几种解决方案供大家参考。
1. 使用@PostConstruct注解
这个注解呢,可以在Spring加载这个类的时候执行一次。来看一下下方代码。
@Component
public class Test {
public Test(){
System.out.println("我最先执行");
}
/**
*第二个执行
*/
@Autowired
private T t;
/**
*第三个个执行
*/
@PostConstruct
private void init(){
}
}
不管是service层,还是controller层,都是可以直接用的,或者是在@component下的都可以用,
2、CommandLineRunner接口
使用CommandLineRunner接口类似于Main方法启动,可以接受一个字符串数组的命令行参数,来看一下实现
@Component
public class MyCommandLineRunner implements CommandLineRunner{
@Override
public void run(String... args) throws Exception{
}
}
项目里面,我采用了这种方法
package com.lingxu.base.config;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lingxu.base.common.constant.CacheConstant;
import com.lingxu.base.common.util.RedisUtil;
import com.lingxu.base.system.manage.entity.SysDict;
import com.lingxu.base.system.manage.entity.SysDictItem;
import com.lingxu.base.system.manage.entity.SysDictTreeItem;
import com.lingxu.base.system.manage.service.ISysDictItemService;
import com.lingxu.base.system.manage.service.ISysDictService;
import com.lingxu.base.system.manage.service.ISysDictTreeItemService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author gxp
* @create 2019/11/13 18:19
* @Ver 1.0.0
*/
@Component
public class SystemInit implements CommandLineRunner {
@Autowired
private ISysDictItemService iSysDictItemService;
@Autowired
private ISysDictService iSysDictService;
@Resource
private ISysDictTreeItemService iSysDictTreeItemService;
@Autowired
private RedisUtil redisUtil;
/**
* 功能描述: 初始化加载数据字典到redis缓存
*
* @param: [args]
* @return: void
* @auther: gxp
* @date: 2019/11/13 18:27
*/
@Override
public void run(String... args) throws Exception {
// 先清空字典
redisUtil.del(CacheConstant.SYS_DICT_CACHE);
redisUtil.del(CacheConstant.SYS_TREE_DICT_CACHE);
Map<String, List<SysDictItem>> map = new HashMap<>();
// 加载系统字典
initSysDict(map);
// 加载字典
redisUtil.set(CacheConstant.SYS_DICT_CACHE, map);
Map<String,String> treeDictMap=new HashMap<>();
initSysTreeDict(treeDictMap);
// 加载字典
redisUtil.set(CacheConstant.SYS_TREE_DICT_CACHE, treeDictMap);
}
private void initSysDict(Map<String, List<SysDictItem>> map) {
LambdaQueryWrapper<SysDict> query = new LambdaQueryWrapper<>();
// 加载平台字典
List<SysDict> dicts = iSysDictService.list(query);
dicts.stream().forEach(dict -> {
List<SysDictItem> items = iSysDictItemService.queryByCodeAndType(dict.getCode(),dict.getDictType());
map.put(dict.getDictType() + "_" + dict.getCode(), items);
});
}
private void initSysTreeDict(Map<String, String> map) {
LambdaQueryWrapper<SysDictTreeItem> query = new LambdaQueryWrapper<>();
// 加载平台字典
List<SysDictTreeItem> dicts = iSysDictTreeItemService.list();
if(CollectionUtils.isNotEmpty(dicts)){
dicts.forEach(d->{
map.put(d.getDictCode()+"_"+d.getValue(),d.getName());
});
}
}
}
3. ApplicationRunner 接口
此种方式与实现CommandLineRunner接口的区别就是他的参数是ApplicationArguments
@Order(value = 1)
@Component
public class MyApplicationRunner implements ApplicationRunner{
@Override
public void run(ApplicationArguments args) throws Exception{
}
}