簡體   English   中英

Spring緩存不適用於子類中的重寫方法

[英]Spring cache not working for overriden methods in a subclass

我無法讓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 }
}

方法查找僅在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,則它可以工作,但這只會破壞繼承。

我看到它是由於類型擦除引起的,但我不知道如何使其正確工作?

Spring Cache Documentation中說接口方法上的@Cache*注釋不適用於基於類的代理。 因此,您應該將@Cache*添加到要緩存的每個類方法。

Spring建議您僅使用@ Cache *注釋對具體類(以及具體類的方法)進行注釋,而不是對接口進行注釋。 您當然可以在接口(或接口方法)上放置@ Cache *批注,但這僅在您使用基於接口的代理時才可以使用。 Java注釋不是從接口繼承的事實意味着,如果您使用的是基於類的代理(proxy-target-class =“ true”)或基於編織的方面(mode =“ aspectj”),則緩存設置為代理和編織基礎結構無法識別該對象,並且該對象也不會包裝在緩存代理中,這肯定是不好的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM