目录
Spring4.1新特性——页面自动化测试框架Spring MVC Test HtmlUnit简介
Spring 4.1提供了对jcache的支持,并对cache抽象部分进行了一些简单的增强。在集成jcache时是非常费劲的,版本之间各种不兼容,不建议用于正式环境,在正式环境中可以使用如Guava Cache或Ehcache。
jcache依赖:
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-jcache</artifactId> <version>${ehcache-jcache.version}</version> </dependency> <dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId> <version>${javax.cache.version}</version> </dependency> <dependency> <groupId>org.jsr107.ri</groupId> <artifactId>cache-ri-impl</artifactId> <version>${cache-ri-impl.version}</version> </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:
javax.cache.CacheManager cacheManager = Caching.getCachingProvider().getCacheManager(); MutableConfiguration<Object, Object> mutableConfiguration = new MutableConfiguration<Object, Object>(); mutableConfiguration.setStoreByValue(false); // otherwise value has to be Serializable cacheManager.createCache("user", mutableConfiguration); cacheManager.createCache("user2", mutableConfiguration); cacheManager.createCache("user3", mutableConfiguration); JCacheCacheManager jCacheCacheManager = new JCacheCacheManager(cacheManager); return jCacheCacheManager;
Java Config方式提供了CachingConfigurer用于提供配置回调:
@Configuration @ComponentScan(basePackages = "com.sishuok.spring.service") @EnableCaching(proxyTargetClass = true) public class AppConfig implements CachingConfigurer { @Bean @Override public CacheManager cacheManager() { javax.cache.CacheManager cacheManager = Caching.getCachingProvider().getCacheManager(); MutableConfiguration<Object, Object> mutableConfiguration = new MutableConfiguration<Object, Object>(); mutableConfiguration.setStoreByValue(false); // otherwise value has to be Serializable cacheManager.createCache("user", mutableConfiguration); cacheManager.createCache("user2", mutableConfiguration); cacheManager.createCache("user3", mutableConfiguration); JCacheCacheManager jCacheCacheManager = new JCacheCacheManager(cacheManager); return jCacheCacheManager; } @Bean @Override public CacheResolver cacheResolver() { return new MyCacheResolver(); } @Bean @Override public KeyGenerator keyGenerator() { return new SimpleKeyGenerator(); } @Override public CacheErrorHandler errorHandler() { return new CacheErrorHandler() { @Override public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) { System.out.println("cache get error"); } @Override public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) { System.out.println("cache put error"); } @Override public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) { System.out.println("cache evict error"); } @Override public void handleCacheClearError(RuntimeException exception, Cache cache) { System.out.println("cache clear error"); } }; } }
2、@CacheConfig指定全局Cache配置
Spring 4.1之前需要每个方法上都指定:
@Service public class UserService { Set<User> users = new HashSet<User>(); @CachePut(value = "user", key = "#user.id") public User save(User user) { users.add(user); return user; } @CachePut(value = "user", key = "#user.id") public User update(User user) { users.remove(user); users.add(user); return user; } @CacheEvict(value = "user", key = "#user.id") public User delete(User user) { users.remove(user); return user; } @CacheEvict(value = "user", allEntries = true) public void deleteAll() { users.clear(); } @Cacheable(value = "user", key = "#id") public User findById(final Long id) { System.out.println("cache miss, invoke find by id, id:" + id); for (User user : users) { if (user.getId().equals(id)) { return user; } } return null; } }
Spring 4.1时可以直接在类级别使用@CacheConfig指定:
@Service @CacheConfig(cacheNames = {"user", "user2"}) public class UserService { Set<User> users = new HashSet<User>(); @CachePut(key = "#user.id") public User save(User user) { users.add(user); return user; } @CachePut(key = "#user.id") public User update(User user) { users.remove(user); users.add(user); return user; } @CacheEvict(key = "#user.id") public User delete(User user) { users.remove(user); return user; } @CacheEvict(allEntries = true) public void deleteAll() { users.clear(); } @Cacheable(key = "#id") public User findById(final Long id) { System.out.println("cache miss, invoke find by id, id:" + id); for (User user : users) { if (user.getId().equals(id)) { return user; } } return null; } }
3、CacheResolver
其名字已经暗示了其是Cache解析器,用于根据实际情况来动态解析使用哪个Cache,如:
public class MyCacheResolver implements CacheResolver { @Autowired private CacheManager cacheManager; @Override public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) { List<Cache> caches = new ArrayList<Cache>(); for(String cacheName : context.getOperation().getCacheNames()) { caches.add(cacheManager.getCache(cacheName)); } if(context.getTarget() instanceof UserService2) { caches.add(cacheManager.getCache("user2")); caches.add(cacheManager.getCache("user3")); } return caches; } }
context中存放了当前cache的操作类型、目标对象、目标方法、参数信息,这样我们可以根据这些信息来决定使用那些cache; context.getOperation().getCacheNames()得到当前目标对象/目标方法上配置的cache Name;然后我们可以在此基础上添加额外的cache。
此处需要注意的是即使配置了CacheResolver,也必须在@CacheConfig或方法上的如@CachePut上指定至少一个Cache Name。
4、CacheErrorHandler
用于捕获从Cache中进行CRUD时的异常的回调处理器。
相关资料
Spring4新特性
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
Spring4新特性——注解、脚本、任务、MVC等其他特性改进
源码下载
https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-cache