【发布时间】:2019-01-25 19:56:53
【问题描述】:
我无法让 Spring 缓存与在超类中实现的子类中覆盖的方法正常工作。 例如,我有这个抽象服务:
public interface CrudService<E, I> {
void deleteById(I id);
E create(E item);
}
public abstract class CrudServiceImpl<E, I> {
void deleteById(I id) { // do things }
...
}
我有几个服务为不同的实体 (E) 和 id 类型 (I) 扩展了这个抽象类。我只想缓存其中一个:
public interface LocationService extends CrudService<Location, String> {
@CacheEvict("location")
@Override
void deleteById(String id);
@Cacheable("location")
List<Location> find();
}
@Service
public class LocationServiceImpl extends CrudServiceImpl<Location, String> implements LocationService {
public List<Location> find() { // do things }
}
方法find只定义在LocationService中,不在抽象类中。 当我从一个也有抽象类的组件中调用这些方法时:
public abstract class CrudManager<E, I> {
@Autowired
private CrudService<E, I> crudService;
public void doDelete(I id) {
crudService.deleteById(id);
}
}
@Component
public class LocationManager extends CrudManager<Location, String> {
@Autowired
private LocationService locationService;
public List<Location> doFind() {
return locationService.find();
}
}
我已经确认,当LocationManager.doFind被调用时,会触发LocationService中定义的缓存操作,但LocationManager.doDelete不会。
我一直调试到 AbstractFallbackCacheOperationSource.getCacheOperations 才意识到它正在搜索操作的方法是:
public default void com.ontech.plantcore.service.LocationService.deleteById(java.lang.Object)
使用 targetClass = LocationServiceImpl.class,而不是我的注释方法 LocationService.deleteById(java.lang.String)。所以 ClassUtils.getMostSpecificMethod 找不到注解的方法,没有操作返回。它发生在 Spring 4.3.14 和 4.1.9 中。
如果我在 LocationManager 中向 locationService.deleteById 添加一个特定调用,它可以工作,但这只会破坏继承。
我看到它是由于类型擦除,但我不知道如何使它正常工作?
【问题讨论】:
-
LocationManager.create的代码在哪里? -
为了简化,我没有包含它。抱歉,我刚刚更改了示例方法并完成了一些缺少的参数。
-
分享到 github repo 的链接比在文本中解析代码要方便得多。这是什么版本的 Spring Framework?
-
Spring 4.3.14 和 4.1.9 也是。嗯,这个例子很简单。
标签: java spring spring-cache