项目中调用Feign接口进行数据初始化
工程中难免需要将一部分数据进行初始化。在工程刚启动完成就进行初始化,方便使用。
推荐使用CommandLineRunner接口,
若使用@PostConstruct注解有多个限制,例如:
- 只有一个非静态方法能使用此注解
- 被注解的方法不得有任何参数
- 被注解的方法返回值必须为void
- 被注解方法不得抛出已检查异常
- 此方法只会被执行一次
- 且该注解标注的方法中不能调用feign接口,除非保证此方法能在feign初始化完成后调用
实现CommandLineRunner接口
重新run方法。在run方法中调用初始化服务中的init方法
@Slf4j
@Component
public class BuzConfigInitRunner implements CommandLineRunner {
@Autowired
private BuzConfigInitService buzConfigInitService;
@Override
public void run(String... args) throws Exception {
try {
buzConfigInitService.init();
} catch (Exception e) {
log.error("初始化方法执行异常:", e);
}
}
}
初始化服务
首先定义初始化结果map,是否完成初始化标志
/**
* key:配置表id
*/
private Map<Long, BuzConfigVO> allConfigIdMap;
/**
* key:configType + configCode -->Map<configType, Map<configCode, BuzConfigVO>>
*/
private Map<ConfigTypeEnum, Map<Long, BuzConfigVO>> configTypeAndConfigCodeMap;
/**
* key: 领域 + 平台id + 分组 + 配置类型;方法genConfigTypeKey
* <p> value:对应配置类型
*/
private final Map<String, List<BuzConfigVO>> collectionCache = new HashMap<>();
/**
* 是否已初始化数据
*/
private boolean inited = false;
初始化方法
在初始化之前,首先判断是否已经初始化
public void init() {
// 若已经初始化,直接返回
if (inited) {
return;
}
// 加锁,防止初始化未完成时,就有服务调用当初初始化完成后的方法,同时也防止多次重新初始化
synchronized (this) {
// 防止初始化过程中出现调用,再此调用init方法,等待执行加锁代码块,而再次执行加锁代码块
if (inited) {
return;
}
try {
log.info("BuzConfig->开始初始化初始化付款业务配置");
long start = System.currentTimeMillis();
List<BuzConfigVO> allConfig = buzConfigApi.findAllConfig();
allConfigIdMap = allConfig.stream()
.collect(
Collectors.toMap(BuzConfigVO::getId, Function.identity(), (x, y) -> x));
configTypeAndConfigCodeMap = allConfig.stream().collect(
Collectors.groupingBy(BuzConfigVO::getConfigType,
Collectors
.toMap(BuzConfigVO::getConfigCode, Function.identity(), (x, y) -> x)));
for (FinDomainEnum domainEnum : FinDomainEnum.values()) {
List<FinAllConfigCollectionVO> allCollection = buzConfigApi
.findAllCollection(domainEnum);
allCollection.forEach(coll -> {
coll.getCollectionTypeVOS().forEach(collType -> {
collType.getBuzConfigTypeVOS().forEach(configType -> {
List<BuzConfigVO> configVOS = configType.getBuzConfigIds().stream()
.map(allConfigIdMap::get).filter(Objects::nonNull)
.collect(Collectors.toList());
String cacheKey = genConfigTypeKey(domainEnum, coll.getPlatformId(),
collType.getCollectionType(), configType.getConfigType());
collectionCache.put(cacheKey, configVOS);
});
});
});
}
log.info("BuzConfig->初始化付款业务配置完成.耗时:{}ms", System.currentTimeMillis() - start);
} catch (Exception e) {
log.error("初始化付款业务配置缓存失败", e);
return;
}
// 初始化完成,标志改为true
inited = true;
}
}
提供方法
使用缓存前,必须先进行初始化
public List<BuzConfigVO> findPayConfigCollection(CollectionTypeEnum collectionType,
ConfigTypeEnum configTypeEnum, String platformId) {
//使用缓存前必须加载
init();
String key = genConfigTypeKey(FinDomainEnum.PAYMENT, platformId, collectionType,
configTypeEnum);
return collectionCache.getOrDefault(key, Collections.emptyList());
}