我正在构建一个“类缓存”,其中包含我想稍后调用的类。
主要目标是我不希望每次需要类实例时都扫描上下文。
# Model / Repository classes
@Getter
@RequiredArgsConstructor
public class Block implements Serializable {
private final String className;
private final Set<String> classCandidates = new HashSet<>();
public boolean addCandidate(final String classCandidate) {
return this.classCandidates.add(classCandidate);
}
}
@Slf4j
@Component
@CacheConfig(cacheNames = ConstantsCache.CACHE_BLOCK)
public class BlockRepository {
@Cacheable(key = "#className")
public Block findByInputClass(final String className) {
log.info("---> Loading classes for class '{}'", className);
val block = new Block(className);
findCandidates(block);
return block;
}
}
首先评估缓存,我将缓存方法@Autowired放在@RestController中,效果很好。当我调用 rest 方法时,缓存被填充。
@RestController
public class Controller {
@Autowired
BlockRepository blockRepository;
@RequestMapping("/findByInputClass")
public Block findByInputClass(@RequestParam("className") final String className) {
return blockRepository.findByInputClass(className);
}
}
之后,我将@Autowired对象移至@Service,创建了一种自行填充缓存的方法。但这不起作用。调用@PostConstructor方法时不会填充缓存。
@Slf4j
@Component
public class BlockCacheService {
@Autowired
BlockRepository blockRepository;
@PostConstruct
private void postConstruct() {
log.info("*** {} PostConstruct called.", this.getClass().getTypeName());
val block = blockRepository.findByInputClass(ConstantsGenerics.BLOCK_PARENT_CLASS);
final Set<String> inputClasses = getInputFromCandidates(block.getClassCandidates());
appendClassesToCache(inputClasses);
}
private void appendClassesToCache(final Set<String> inputClasses) {
for (val inputClass : inputClasses) {
blockRepository.findByInputClass(inputClass);
}
}
}
如何使用必须从应用程序开始的服务或组件正确填充缓存。
提前致谢。
编辑:
我在这里找到了一个可能的解决方案:https ://stackoverflow.com/a/28311225/1703546
比我更改了@Service代码以手动放置缓存而不是使用@Cacheable魔术抽象。
现在的课是这样的。
@Slf4j
@Component
public class BlockCacheService {
@Autowired
CacheManager cacheManager;
@Autowired
BlockRepository blockRepository;
@PostConstruct
private void postConstruct() {
log.info("*** {} PostConstruct called.", this.getClass().getTypeName());
val block = blockRepository.findByInputClass(ConstantsGenerics.BLOCK_PARENT_CLASS);
final Set<String> inputClasses = getInputFromCandidates(block.getClassCandidates());
appendClassesToCache(inputClasses);
}
private void appendClassesToCache(final Set<String> inputClasses) {
for (val inputClass : inputClasses) {
val block = blockRepository.findByInputClass(inputClass);
cacheManager.getCache(ConstantsCache.CACHE_BLOCK).put(block.getClassName(), block);
}
}
}
现在缓存已正确填充,但问题是,这是最好的解决方案吗?
谢谢。