问题:
项目中有一个文件类型表,通过文件后缀获取文件类型,存放在数据库中。由于文件过多,每次遍历文件获取文件类型都需要查询数据库,且我们没有搭Redis等缓存数据库,所以需要在服务启动的时候将数据数据库加载到内存中。
解决办法:使用的是第二种
1、使用static{}静态块儿
通过@Component注解在服务启动注入是调用static块儿中的逻辑查询数据库存入内存; 在类上使用@Component注解加载时注入类,然后再static{}静态块儿。
2、使用@PostConstruct注解
被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。PreDestroy()方法在destroy()方法执行之后执行。
@Component
public class FileTypeDetector {
/**
* 日志
*/
private final static Logger logger = LoggerFactory.getLogger(FileTypeDetector.class);
@Autowired
private FileSuffixMappingBiz fileSuffixMappingBiz;
private static final String UNKNOWN_TYPE = "unkown_type";
public static List<FileSuffixMapping> fileSuffixMappings = new ArrayList<>();
/**
* @Description:
*
* @param
* @Return: void
* @Author: xxx
* @Date: 2019/xx/xx
*/
@PostConstruct
public void initFileSuffix() {
//在服务启动时查询数据库数据存入static形式的list中
fileSuffixMappings = fileSuffixMappingBiz.selectFileSuffix();
}
public static String detect(String fileName) {
//如果文件名为空,返回无效type
if (StringUtils.isBlank(fileName)) {
return UNKNOWN_TYPE;
}
//获取后缀
String fileSuffix = fileName.substring(fileName.lastIndexOf(".") > 0 ? fileName.lastIndexOf(".") : 0);
if (fileSuffixMappings.stream().anyMatch(item -> fileSuffix.equals(item.getFileSuffix()))) {
return fileSuffix;
} else {
return UNKNOWN_TYPE;
}
}
/**
* @Description: 根据文件名判断文件是否是已知的类型
*
* @param fileName
* @Return: boolean
* @Author: xxx
* @Date: 2019/8/16
*/
public static boolean isKnownTypeByName(String fileName) {
final String typeHint = detect(fileName);
return !typeHint.equals(UNKNOWN_TYPE);
}
/**
* @Description: 根据文件名获取文件的类型
*
* @param fileName
* @Return: boolean
* @Author: xxx
* @Date: 2019/8/16
*/
public static String getFileTypeByFileName(String fileName) {
String fileType = UNKNOWN_TYPE;
//如果文件名为空,返回无效type
if (StringUtils.isBlank(fileName)) {
return fileType;
}
//获取后缀
String fileSuffix = fileName.substring(fileName.lastIndexOf(".") > 0 ? fileName.lastIndexOf(".") : 0);
for (FileSuffixMapping fileSuffixMapping : fileSuffixMappings) {
if (fileSuffix.equalsIgnoreCase(fileSuffixMapping.getFileSuffix())) {
fileType = fileSuffixMapping.getFileType();
break;
}
}
return fileType;
}
}
3、定时同步数据库数据到内存中
由于可能遇到需要往数据库中加一些文件类型,所以要定时同步数据库数据,这样就不用每次修改了数据库都要重启服务,只需等待5分钟即可。这里用到quartz定时任务。
@Component
public class FileTypeSyncScheduled {
public static final Logger logger = LoggerFactory.getLogger(FileTypeSyncScheduled.class);
@Autowired
private FileTypeDetector fileTypeDetector;
/**
* 是否同步数据库开关
*/
@Value("${file.type.sync.open}")
private Boolean fileSyncOpen;
/**
* @Description: 每5分钟同步数据库数据到内存中
* 0 0/5 * * * ?
* @param
* @Return: void
* @Author: xxx
* @Date: 2019/8/16
*/
@Scheduled(cron = "${file.cron}")
public void syncFileType() {
//校验开关
if (!fileSyncOpen) {
return;
}
logger.info("***************************** 开始从数据库同步文件类型到内存中 *****************************");
try {
fileTypeDetector.initFileSuffix();
} catch (Exception e) {
logger.error("从数据库同步文件类型到内存中出现异常!", e);
}
}
}
版权声明:本文为sayoko06原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。