Affects: 6.0
AbstractService.java
public abstract class AbstractService<T extends AbstractModel, PK extends Serializable> {
protected BaseMapper<T, PK> baseMapper;
@Transactional
@CacheEvict(key = "#p0.id")
public void update(Converter<T> param, Consumer<T> consumer) {
T modelDO = prepare(param, consumer);
if (!existByPK(modelDO.getId())) {
throw new BusinessException(404, MessageUtils.getMessage("id.not-found"));
}
baseMapper.updateByPrimaryKeySelective(modelDO);
}
@Transactional
@CacheEvict(key = "#p0")
public void deleteById(PK id) {
if (!existByPK(id)) {
throw new BusinessException(404, MessageUtils.getMessage("id.not-found"));
}
baseMapper.deleteByPrimaryKey(id);
}
}
PermService.java
@Service
@CacheConfig(cacheNames = "perm")
public class PermService extends AbstractService<PermDO, String> {
public List<PermDTO> listPerm() {
return baseMapper.wrapper().list().stream().map(Converter::convert).toList();
}
}
i want to use @Cacheable in AbstractService, but I cannot provide cacheNames in AbstractService, how can i define cacheNames in sub class?
I tried to modify SpringCacheAnnotationParser, but I found that the Collection < CacheOperation > parseCacheAnnotations (Method method) of the CacheAnnotationParser interface; only method was passed in the parameter, not the subclass class, so parsing method.getDeclareClass got AbstractService
Collection<CacheOperation> parseCacheAnnotations(Method method);
Comment From: bclozel
Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use the issue tracker only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.
Comment From: L1yp
Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use the issue tracker only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.
I can handle this in CacheResolver, but I think Spring-Cache, as an abstract cache, should consider the situation where cacheNames cannot be provided when abstracting Service
@Override
@NotNull
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
Collection<String> cacheNames = context.getOperation().getCacheNames();
if (CollectionUtils.isEmpty(cacheNames)) {
// 读取实现类的CacheConfig上的cacheNames
Class<?> declaringClazz = context.getMethod().getDeclaringClass();
Class<?> targetClazz = context.getTarget().getClass();
if (Modifier.isAbstract(declaringClazz.getModifiers())) {
if (targetClazz.isAnnotationPresent(CacheConfig.class)) {
CacheConfig cacheConfig = targetClazz.getAnnotation(CacheConfig.class);
String[] cachedNames = cacheConfig.cacheNames();
if (cachedNames.length > 0) {
context.getOperation().getCacheNames().addAll(List.of(cacheConfig.cacheNames()));
}
}
}
}
//... other
}