1. 程式人生 > >Sping cache 資料(一。Spring4.1新特性——Spring快取框架增強)

Sping cache 資料(一。Spring4.1新特性——Spring快取框架增強)

Spring 4.1提供了對jcache的支援,並對cache抽象部分進行了一些簡單的增強。在整合jcache時是非常費勁的,版本之間各種不相容,不建議用於正式環境,在正式環境中可以使用如Guava Cache或Ehcache。

 

jcache依賴:

Java程式碼   收藏程式碼
  1. <dependency>  
  2.     <groupId>net.sf.ehcache</groupId>  
  3.     <artifactId>ehcache-jcache</artifactId>  
  4.     <version>${ehcache-jcache.version}</version>  
  5. </dependency>  
  6. <dependency>  
  7.     <groupId>javax.cache</groupId>  
  8.     <artifactId>cache-api</artifactId>  
  9.     <version>${javax.cache.version}</version>  
  10. </dependency>  
  11. <dependency>  
  12.     <groupId>org.jsr107.ri</groupId>  
  13.     <artifactId>cache-ri-impl</artifactId>  
  14.     <version>${cache-ri-impl.version}</version>  
  15. </dependency>    

<javax.cache.version>1.0.0</javax.cache.version>、<cache-ri-impl.version>1.0.0</cache-ri-impl.version>、<ehcache-jcache.version>1.2</ehcache-jcache.version>,具體請參考原始碼。

 

1、Jcache整合

建立Cache: 

Java程式碼   收藏程式碼
  1. javax.cache.CacheManager cacheManager = Caching.getCachingProvider().getCacheManager();  
  2. MutableConfiguration<Object, Object> mutableConfiguration = new MutableConfiguration<Object, Object>();  
  3. mutableConfiguration.setStoreByValue(false);  // otherwise value has to be Serializable  
  4. cacheManager.createCache("user", mutableConfiguration);  
  5. cacheManager.createCache("user2", mutableConfiguration);  
  6. cacheManager.createCache("user3", mutableConfiguration);  
  7.   
  8. JCacheCacheManager jCacheCacheManager = new JCacheCacheManager(cacheManager);  
  9. return jCacheCacheManager;  

 

Java Config方式提供了CachingConfigurer用於提供配置回撥:   

Java程式碼   收藏程式碼
  1. @Configuration  
  2. @ComponentScan(basePackages = "com.sishuok.spring.service")  
  3. @EnableCaching(proxyTargetClass = true)  
  4. public class AppConfig implements CachingConfigurer {  
  5.     @Bean  
  6.     @Override  
  7.     public CacheManager cacheManager() {  
  8.         javax.cache.CacheManager cacheManager = Caching.getCachingProvider().getCacheManager();  
  9.         MutableConfiguration<Object, Object> mutableConfiguration = new MutableConfiguration<Object, Object>();  
  10.         mutableConfiguration.setStoreByValue(false);  // otherwise value has to be Serializable  
  11.         cacheManager.createCache("user", mutableConfiguration);  
  12.         cacheManager.createCache("user2", mutableConfiguration);  
  13.         cacheManager.createCache("user3", mutableConfiguration);  
  14.   
  15.         JCacheCacheManager jCacheCacheManager = new JCacheCacheManager(cacheManager);  
  16.         return jCacheCacheManager;  
  17.     }  
  18.   
  19.     @Bean  
  20.     @Override  
  21.     public CacheResolver cacheResolver() {  
  22.         return new MyCacheResolver();  
  23.     }  
  24.   
  25.     @Bean  
  26.     @Override  
  27.     public KeyGenerator keyGenerator() {  
  28.         return new SimpleKeyGenerator();  
  29.     }  
  30.   
  31.     @Override  
  32.     public CacheErrorHandler errorHandler() {  
  33.         return new CacheErrorHandler() {  
  34.             @Override  
  35.             public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {  
  36.                 System.out.println("cache get error");  
  37.             }  
  38.   
  39.             @Override  
  40.             public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {  
  41.                 System.out.println("cache put error");  
  42.             }  
  43.   
  44.             @Override  
  45.             public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {  
  46.                 System.out.println("cache evict error");  
  47.             }  
  48.   
  49.             @Override  
  50.             public void handleCacheClearError(RuntimeException exception, Cache cache) {  
  51.                 System.out.println("cache clear error");  
  52.             }  
  53.         };  
  54.     }  
  55. }  

 

 

2、@CacheConfig指定全域性Cache配置

Spring 4.1之前需要每個方法上都指定: 

Java程式碼   收藏程式碼
  1. @Service  
  2. public class UserService {  
  3.   
  4.     Set<User> users = new HashSet<User>();  
  5.   
  6.     @CachePut(value = "user", key = "#user.id")  
  7.     public User save(User user) {  
  8.         users.add(user);  
  9.         return user;  
  10.     }  
  11.   
  12.     @CachePut(value = "user", key = "#user.id")  
  13.     public User update(User user) {  
  14.         users.remove(user);  
  15.         users.add(user);  
  16.         return user;  
  17.     }  
  18.   
  19.     @CacheEvict(value = "user", key = "#user.id")  
  20.     public User delete(User user) {  
  21.         users.remove(user);  
  22.         return user;  
  23.     }  
  24.   
  25.     @CacheEvict(value = "user", allEntries = true)  
  26.     public void deleteAll() {  
  27.         users.clear();  
  28.     }  
  29.   
  30.     @Cacheable(value = "user", key = "#id")  
  31.     public User findById(final Long id) {  
  32.         System.out.println("cache miss, invoke find by id, id:" + id);  
  33.         for (User user : users) {  
  34.             if (user.getId().equals(id)) {  
  35.                 return user;  
  36.             }  
  37.         }  
  38.         return null;  
  39.     }  
  40.   
  41. }  

 

 

Spring 4.1時可以直接在類級別使用@CacheConfig指定: 

Java程式碼   收藏程式碼
  1. @Service  
  2. @CacheConfig(cacheNames = {"user""user2"})  
  3. public class UserService {  
  4.   
  5.     Set<User> users = new HashSet<User>();  
  6.   
  7.     @CachePut(key = "#user.id")  
  8.     public User save(User user) {  
  9.         users.add(user);  
  10.         return user;  
  11.     }  
  12.   
  13.     @CachePut(key = "#user.id")  
  14.     public User update(User user) {  
  15.         users.remove(user);  
  16.         users.add(user);  
  17.         return user;  
  18.     }  
  19.   
  20.     @CacheEvict(key = "#user.id")  
  21.     public User delete(User user) {  
  22.         users.remove(user);  
  23.         return user;  
  24.     }  
  25.   
  26.     @CacheEvict(allEntries = true)  
  27.     public void deleteAll() {  
  28.         users.clear();  
  29.     }  
  30.   
  31.     @Cacheable(key = "#id")  
  32.     public User findById(final Long id) {  
  33.         System.out.println("cache miss, invoke find by id, id:" + id);  
  34.         for (User user : users) {  
  35.             if (user.getId().equals(id)) {  
  36.                 return user;  
  37.             }  
  38.         }  
  39.         return null;  
  40.     }  
  41. }  

 

3、CacheResolver

其名字已經暗示了其是Cache解析器,用於根據實際情況來動態解析使用哪個Cache,如: 

Java程式碼   收藏程式碼
  1. public class MyCacheResolver implements CacheResolver {  
  2.   
  3.     @Autowired  
  4.     private CacheManager cacheManager;  
  5.   
  6.     @Override  
  7.     public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {  
  8.         List<Cache> caches = new ArrayList<Cache>();  
  9.         for(String cacheName : context.getOperation().getCacheNames()) {  
  10.             caches.add(cacheManager.getCache(cacheName));  
  11.         }  
  12.         if(context.getTarget() instanceof UserService2) {  
  13.             caches.add(cacheManager.getCache("user2"));  
  14.             caches.add(cacheManager.getCache("user3"));  
  15.         }  
  16.         return caches;  
  17.     }  
  18. }  

context中存放了當前cache的操作型別、目標物件、目標方法、引數資訊,這樣我們可以根據這些資訊來決定使用那些cache; context.getOperation().getCacheNames()得到當前目標物件/目標方法上配置的cache Name;然後我們可以在此基礎上新增額外的cache。

 

 

此處需要注意的是即使配置了CacheResolver,也必須在@CacheConfig或方法上的如@CachePut上指定至少一個Cache Name。

 

4、CacheErrorHandler

用於捕獲從Cache中進行CRUD時的異常的回撥處理器。