2012-08-24 35 views
35

Có cách nào để chỉ định rằng nếu phương thức trả về giá trị rỗng, thì không lưu kết quả trong chú thích @Cacheable cho một phương thức như thế này?Làm cách nào để báo cho bộ đệm ẩn không lưu trữ giá trị null trong chú thích @Cacheable

@Cacheable(value="defaultCache", key="#pk") 
public Person findPerson(int pk) { 
    return getSession.getPerson(pk); 
} 

Cập nhật: đây là vấn đề JIRA nộp liên quan đến bộ nhớ đệm giá trị null cuối tháng mười một, mà đã không được giải quyết chưa: [#SPR-8871] @Cachable condition should allow referencing return value - Spring Projects Issue Tracker

+0

Xin chào, tôi nghĩ bạn nên trả lời câu hỏi của Tech Trip khi được chấp nhận vì nó phù hợp hơn với phiên bản Spring hiện tại. –

Trả lời

59

Hoan hô, tính đến mùa xuân 3.2 khung cho phép sử dụng Spring SPEL và unless. Lưu ý từ doc java xung quanh Cacheable:

http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/cache/annotation/Cacheable.html

public String trừu tượng trừ

Xuân Expression Language (SpEL) thuộc tính dùng để phủ quyết phương pháp bộ nhớ đệm.

Không giống như điều kiện(), biểu thức này được đánh giá sau khi phương thức đã được gọi và do đó có thể tham khảo kết quả. Mặc định là "", có nghĩa là bộ nhớ đệm không bao giờ bị phủ nhận.

Khía cạnh quan trọng là unless được đánh giá sau khi phương pháp đã được gọi. Điều này làm cho cảm giác hoàn hảo bởi vì phương pháp sẽ không bao giờ được thực hiện nếu khóa đã có trong bộ nhớ cache.

Vì vậy, trong ví dụ trên bạn chỉ đơn giản là sẽ chú thích như sau (#result có sẵn để kiểm tra giá trị trả về của một phương pháp):

@Cacheable(value="defaultCache", key="#pk", unless="#result == null") 
public Person findPerson(int pk) { 
    return getSession.getPerson(pk); 
} 

tôi sẽ tưởng tượng tình trạng này phát sinh từ việc sử dụng bộ nhớ cache triển khai pluggable chẳng hạn như Ehcache cho phép bộ nhớ đệm của null. Tùy thuộc vào tình huống sử dụng của bạn, điều này có thể hoặc không được mong muốn.

+0

Xin chào, tôi có một kịch bản, trong đó redis caching server lưu trữ các ngoại lệ. Tôi phải tránh bộ nhớ đệm của ngoại lệ cho máy chủ. Tôi có thể sử dụng tham số "trừ khi" cho việc này không? Có thể đề cập đến ngoại lệ trừ khi không? Vui lòng chia sẻ đề xuất của bạn.Cảm ơn trước – nijogeorgep

+0

JSR107 cung cấp một cơ chế để luôn gọi phương thức được chú thích và vẫn lưu lại kết quả qua cacheResult # skipGet. Theo API trên skipGet, Nếu đúng thì việc kiểm tra trước lời gọi cho một ngoại lệ được ném cũng bị bỏ qua. Tuy nhiên, nếu một ngoại lệ được ném trong khi gọi, nó sẽ được lưu trữ theo các quy tắc bộ nhớ đệm ngoại lệ tiêu chuẩn để có thể không đủ cho nhu cầu của bạn. Tuy nhiên, bằng cách sử dụng JSR 107, bạn có thể loại bỏ một cách rõ ràng một số ngoại lệ nhất định trên cấu hình và có lẽ điều đó sẽ cho phép bạn có đủ thời gian để tiếp tục. (xem nonCachedExceptions) Sự trừu tượng của Spring cung cấp hỗ trợ chú thích JSR107. – TechTrip

2

cập nhật câu trả lời này là lỗi thời bây giờ, cho mùa xuân 3.2 và sau hãy xem answer, OP: Hãy cảm thấy tự do để đánh dấu nó là được chấp nhận.

Tôi không nghĩ rằng nó có thể (mặc dù có điều kiện cache đuổi trong mùa xuân có thể được thực hiện sau khi phương pháp gọi với @CacheEvict tham số beforeInvocation thiết lập để sai sự thật, đó là giá trị mặc định) kiểm tra các lớp CacheAspectSupport cho thấy giá trị trả lại không được lưu trữ ở bất kỳ đâu trước cuộc gọi inspectAfterCacheEvicts(ops.get(EVICT));.

protected Object execute(Invoker invoker, Object target, Method method, Object[] args) { 
    // check whether aspect is enabled 
    // to cope with cases where the AJ is pulled in automatically 
    if (!this.initialized) { 
     return invoker.invoke(); 
    } 

    // get backing class 
    Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target); 
    if (targetClass == null && target != null) { 
     targetClass = target.getClass(); 
    } 
    final Collection<CacheOperation> cacheOp = getCacheOperationSource().getCacheOperations(method, targetClass); 

    // analyze caching information 
    if (!CollectionUtils.isEmpty(cacheOp)) { 
     Map<String, Collection<CacheOperationContext>> ops = createOperationContext(cacheOp, method, args, target, targetClass); 

     // start with evictions 
     inspectBeforeCacheEvicts(ops.get(EVICT)); 

     // follow up with cacheable 
     CacheStatus status = inspectCacheables(ops.get(CACHEABLE)); 

     Object retVal = null; 
     Map<CacheOperationContext, Object> updates = inspectCacheUpdates(ops.get(UPDATE)); 

     if (status != null) { 
      if (status.updateRequired) { 
       updates.putAll(status.cUpdates); 
      } 
      // return cached object 
      else { 
       return status.retVal; 
      } 
     } 

     retVal = invoker.invoke(); 

     inspectAfterCacheEvicts(ops.get(EVICT)); 

     if (!updates.isEmpty()) { 
      update(updates, retVal); 
     } 

     return retVal; 
    } 

    return invoker.invoke(); 
} 
0

Nếu mùa xuân chú thích

@Cacheable(value="defaultCache", key="#pk",unless="#result!=null") 

không làm việc, bạn có thể thử:

@CachePut(value="defaultCache", key="#pk",unless="#result==null") 

Nó làm việc cho tôi.

+5

bạn có nghĩa là 'trừ =" # result == null "'? – cahen

+0

_Cache trừ khi kết quả! = Null_means _Cache nếu kết quả == null_. Vì vậy, biểu thức chính xác là 'trừ =" # result == null "' có nghĩa là _Cache trừ khi kết quả == null_ có nghĩa là _Cache nếu kết quả! = Null_. – mmdemirbas

Các vấn đề liên quan