springboot中使用ApplicationRunner接口
applicationRunner使用
Spring Boot如何解决项目启动时初始化资源,在我们实际工作中,总会遇到这样需求,在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等。
实际操作:
原因:
项目中某个接口速度过慢,然后需要加载字典表里面的数据进行left join ,如下图,进行了两次字典表的left join ,当Unit_info表数据量很大的时候,就会很慢。
操作:
将字典表的数据一开始就加载进来,然后在单位表里面进行直接取出,剩下的value和name对应直接在service层处理了,不耽误mysql资源了。
package com.gstanzer.microservice.unit.safety.common;
import com.gstanzer.microservice.unit.safety.common.mapper.SysDictMapper;
import com.gstanzer.microservice.unit.safety.common.po.SysDict;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Title: InitParamConfig
*
* @author wuwwangsheng
* @version 1.0
* @description: 初始化参数
* @Copyright: Copyright (c) 2022
* @Company: gstanzer
* @date 2022年04月11日
*/
@Component
public class InitParamConfig implements ApplicationRunner {
private static final Logger logger = LoggerFactory.getLogger(InitParamConfig.class);
public static Map<String, Object> paramMap = new ConcurrentHashMap<>();
@Resource
private SysDictMapper sysDictMapper;
@Override
public void run(ApplicationArguments args) throws Exception {
logger.info("==========开始加载数据字典数据===========");
List<SysDict> list = sysDictMapper.selectList(null);
if(!CollectionUtils.isEmpty(list)) {
for(SysDict sysDict:list) {
setParamMap(sysDict);
}
}
logger.info("==========结束加载数据字典数据===========");
}
public static String queryNameByValue(String paramType, String value) {
if (StringUtils.isEmpty(value) || StringUtils.isEmpty(paramType)) {
return "";
}
Object obj = paramMap.get(paramType + "-" + value);
if (obj != null) {
return obj.toString();
}
return "";
}
public static void setParamMap(SysDict sysDict) {
paramMap.put(sysDict.getType() + "-" + sysDict.getValue(), sysDict.getName());
}
}
作用:
在每次项目启动的时候
本地启动:debug启动:+服务器上面sh start .sh
都会在
20:41:50.113 [main] INFO c.g.m.unit.safety.Application - Started Application in 22.742 seconds (JVM running for 24.118)
后面进行applicationRunner接口,实现初始化资源作用。
20:41:50.113 [main] INFO c.g.m.unit.safety.Application - Started Application in 22.742 seconds (JVM running for 24.118)
20:41:50.125 [main] INFO c.g.m.u.s.common.InitParamConfig - ==========开始加载数据字典数据===========
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7167ca15] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1118813413 wrapping com.mysql.cj.jdbc.ConnectionImpl@25c962b7] will not be managed by Spring
==> Preparing: SELECT id,name,value,type,description,sort,parent_id,remark,del_flag FROM sys_dict
==> Parameters:
<== Columns: id, name, value, type, description, sort, parent_id, remark, del_flag
<== Row: 1, 一般单位, 1, unit_attribute, null, 1, 0, null, 0
<== Row: 2, 宾馆(饭店), 2, unit_attribute, null, 2, 1, null, 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7167ca15]
20:41:50.298 [main] INFO c.g.m.u.s.common.InitParamConfig - ==========结束加载数据字典数据===========
20:41:50.817 [RMI TCP Connection(2)-10.9.10.40] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
20:41:50.817 [RMI TCP Connection(2)-10.9.10.40] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
20:41:50.833 [RMI TCP Connection(2)-10.9.10.40] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 16 ms
问题:
这里接口的实现是在初始化dispatcherServlet之前做的处理?
.s.web.servlet.DispatcherServlet - Completed initialization in 16 ms
#### 问题:
> 这里接口的实现是在初始化dispatcherServlet之前做的处理?
>
> 在dispatherServlet之前就说明这个路径没走handlerMappering进行映射,直接在实现类里面进行操作的。