Java Spring缓存不适用于子类中的重写方法
我无法让SpringCache在超类中实现的子类中重写方法时正常工作。 例如,我有一个抽象服务:Java Spring缓存不适用于子类中的重写方法,java,spring,spring-cache,Java,Spring,Spring Cache,我无法让SpringCache在超类中实现的子类中重写方法时正常工作。 例如,我有一个抽象服务: 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 } ... } 使用targetC
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 }
...
}
使用targetClass=LocationServiceImpl.class,而不是我的带注释的方法LocationService.deleteById(java.lang.String)。因此ClassUtils.getMostSpecificMethod无法找到带注释的方法,并且没有返回任何操作。它发生在弹簧4.3.14和4.1.9中
如果我在LocationManager中向locationService.deleteById添加一个特定的调用,它会工作,但这只会破坏继承
我知道这是由于类型擦除,但我不知道如何使其正常工作?中说@Cache*
接口方法上的注释不适用于基于类的代理。因此,您应该将@Cache*
添加到每个要缓存的类方法中
Spring建议只注释具体的类(和方法)
使用@Cache*注释,而不是
注释接口。您当然可以放置@Cache*注释
在接口(或接口方法)上,但这仅在
如果您使用的是基于接口的代理,则可能会出现这种情况。事实
Java注释不是从接口继承的,这意味着
您正在使用基于类的代理(proxy target class=“true”)或
基于编织的方面(mode=“aspectj”),则缓存设置为
代理和编织基础架构未识别,以及
对象将不会包装在缓存代理中,这将是
非常糟糕
关于
LocationManager.create
的代码在哪里?为了简化,我没有包括它。很抱歉,我刚刚更改了示例方法并完成了一些缺少的参数。共享到github repo的链接比解析文本中的代码要方便得多。这是什么版本的Spring框架?也是Spring 4.3.14和4.1.9。这个例子很简单,我没有说任何时候我都在使用基于类的代理。我实际上没有使用它们,这是默认配置,因此对接口进行注释是正确的。无论如何,我已经尝试过将注释放入类中,但没有任何改变。我检查了对象是否用代理包装。但问题在于Spring代码检测方法是否有缓存注释,由于类型擦除,该方法丢失。
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 }
}
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();
}
}
public default void com.ontech.plantcore.service.LocationService.deleteById(java.lang.Object)