1.介绍
Spring 3.1 引入了激动人心的基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如 EHCache 或者 OSCache),而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存方法的返回对象的效果。
Spring 的缓存技术还具备相当的灵活性,不仅能够使用 SpEL(Spring Expression Language)来定义缓存的 key 和各种 condition,还提供开箱即用的缓存临时存储方案,也支持和主流的专业缓存例如 EHCache 集成。
2.maven依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
当然,这个依赖,我们在前面的框架搭建中已经引入
3.配置文件
在spring-context.xml中引入:
<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
<cache:annotation-driven cache-manager="scacheManager"/>
<!--为了区别shiro中引用的id="cacheManager"-->
<bean id="scacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!--这边我们使用的是spring默认的缓存bean,我们也可以根据实际情况进行自定义-->
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="skyCache"/>
</set>
</property>
</bean>
这里先展示一个完全自定义的缓存实现,即不用任何第三方的组件来实现某种对象的内存缓存。
4.注解
spring的cache的缓存方法既适用于dao层,也适用于service层,我这边加载dao实现类上,
@Override
//value是必选项,定义了使用的缓存集合,key如果不定义时默认为方法的参数.key采用的是SpEL表达式
@Cacheable(value = "skyCache", key = "#username")
public User findOneByUsername(String username) {
Query query = new Query();
Criteria criteria = Criteria.where("username").is(username);
query.addCriteria(criteria);
return this.mongoTemplate.findOne(query, User.class);
}
缓存注解有以下三个:
@Cacheable @CacheEvict @CachePut
@Cacheable(value=”skyCache”),这个注释的意思是,当调用这个方法的时候,会从一个名叫 skyCache 的缓存中查询,如果没有,则执行实际的方法(即查询数据库),并将执行的结果存入缓存中,否则返回缓存中的对象。
@CacheEvict 注释来标记要清空缓存的方法,当这个方法被调用后,即会清空缓存。
@CachePut 注释,这个注释可以确保方法被执行,也就是说无论缓存里是否有这个key,都会执行此方法,同时方法的返回值也被记录到缓存中,实现缓存与数据库的同步更新。
注解详细介绍,可以参照开涛老师的文章 点击打开链接 上面的value=“skyCache”与spring-contex.xml里的scacheManager中p:name="skyCache"对应,userDaoImpl中的的其他代码
5.测试
@Autowired
private CacheManager scacheManager;
@Test
public void findOneByUsername() {
logger.info("-------default:-------" + scacheManager.getCache("default"));
logger.info("-------skyCache:-------" + scacheManager.getCache("skyCache"));
User use = userDao.findOneByUsername("skyLine");
logger.info("-------default:-------" + scacheManager.getCache("default"));
logger.info("-------skyCache:-------" + scacheManager.getCache("skyCache"));
}
结果如下:
第一次请求的时候,由于没有往缓存里放置,所以会查询数据库,第二次请求的时候,缓存里已经有了,直接会从缓存里获取,
spring自带的缓存机制cache比较简单,只能解决一些基本的使用,有很大局限性,因此spring也支持扩展,
下一篇将介绍spring采用redis缓存机制。