我正在建立一个“类缓存”,我想稍后调用类。
主要的目标是,我不希望每次需要类实例时都扫描上下文。
# 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);
}
}
}
现在缓存填充正确了,但问题是,这是最好的解决方案?
多谢了。
您不能在@postconstruct
中使用一个方面,因为它可能还没有创建(顺便说明一下)。
一种可行的方法是实现smartinitializingbean
,因为它在所有单例都已完全初始化(包括它们的方面)时会给出回调。
说到这里,你的这段代码对启动时间有影响。为什么你不让你的缓存被懒洋洋地填满呢?
我正在使用spring,我想在启动我的应用程序之前缓存一些数据。 我在其他帖子中找到了一些使用@PostConstruct来调用我的@Service方法的解决方案(这些方法被注释为@Cacheable),例如。如何在spring启动时加载@Cache?我这样做了,但当应用程序启动后,我调用RESTendpoint,它再次调用这个服务方法,它会在另一次发送数据库请求(所以它还没有缓存)。当我第二次向
我需要为我的bean类提供一些配置。在普通的Spring应用程序中,我使用@PostConstruct,但在Play 2.4中似乎不起作用
我正在寻找集成Hazelcast到我的应用程序... 我的要求是将所有数据加载到缓存并从缓存中提取。。 我有两个选择。 1) Hazelcast IMap 2)因为我使用的是Spring启动,所以我可以使用(@Cacheable/@CacheEvict)。 我能得到一些建议吗... 提前谢谢你。。
我正在用 我正在使用 我已经查看了Picturefill的演示,甚至还有一个与我使用的方式非常接近的示例 有没有其他人遇到过这种情况,或者对如何修复它有什么建议?如果我使用src而不是srcset,这似乎是可行的,但我知道不建议将src与Picturefill一起使用,因为它会在不支持srcset的浏览器中导致双重下载。
在我的项目中,我使用了一个@Cacheable注释ia一个服务方法,它返回涉及书籍和一些标记的计算结果,我想在一个@Controller类方法中退出缓存,该方法将一本新书添加到数据库中,因为这本新书将是新计算所必需的。 服务类:@Cacheable("metas") 控制器类:@RequestMapping@CacheEvict(value=“metas”,allEntries=true)
我为我的网站创建了一个AMP页面,在我的桌面浏览器上运行正常,在我的手机上测试正常,如果某些字段为空或无效,提交错误将正确显示错误消息,并且在成功提交时,它将正确显示提交成功消息。 当我将页面提交给Google缓存amp页面时,我再次测试了表单,这次它没有显示错误或成功消息。但如果表单提交有效,它将向我发送电子邮件,但不会显示成功消息。 表单html代码: PHP页面: