Spring Cache 使用 ---@EnableCaching @Cacheable 注解

Spring 3.1 引入了激动人心的基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如 EHCache 或者 OSCache),而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存方法的返回对象的效果。

Spring 的缓存技术还具备相当的灵活性,不仅能够使用 SpEL(Spring Expression Language)来定义缓存的 key 和各种 condition,还提供开箱即用的缓存临时存储方案,也支持和主流的专业缓存例如 EHCache 集成。

服务类

package com.learn.frame.spring.cache;

import org.springframework.cache.annotation.Cacheable;

public class Book {
	/**
	 * value : 缓存的名字  ,key : 缓存map中的key
	 * @param id
	 * @return
	 */
    @Cacheable(value = { "sampleCache" },key="#id")
    public String getBook(int id) {
        System.out.println("Method executed..");
        if (id == 1) {
            return "Book 1";
        } else {
            return "Book 2";
        }
    }
}

 

@Cacheable(value=“sampleCache”),这个注释的意思是,当调用这个方法的时候,会从一个名叫 sampleCache 的缓存(缓存本质是一个map)中查询key为id的值,如果不存在,则执行实际的方法(即查询数据库等服务逻辑),并将执行的结果存入缓存中,否则返回缓存中的对象。这里的缓存中的 key 就是参数 id,value 就是 返回的String 对象 

@Cacheable的使用   

1.value : 指定一个或多个Cache名字,同属性cacheNames

@Cacheable(value ="sampleCache")
@Cacheable(cacheNames="sampleCache")

2.key : 存储对象的key 

a)使用自定义策略  (#参数名 或 #参数.属性名 ) 的方式动态定义key
除了使用方法参数作为key,我还可以使用root对象来生成key

属性名称

描述

示例

methodName

当前方法名

#root.methodName

method

当前方法

#root.method.name

target

当前被调用的对象

#root.target

targetClass

当前被调用的对象的class

#root.targetClass

args

当前方法参数组成的数组

#root.args[0]

caches

当前被调用的方法使用的Cache

#root.caches[0].name

 

1.spring 默认使用root对象属性,#root可以省略

 @Cacheable(value = { "sampleCache" ,"sampleCache2"},key="cache[1].name")
    public String getBook(int id) {
        System.out.println("Method executed..");
        if (id == 1) {
            return "Book 1";
        } else {
            return "Book 2";
        }
    }

2.自定义  key = 类名.方法名.参数值  添加字符用单引号

@Cacheable(value = { "sampleCache","sampleCache2" },key="targetClass.getName()+'.'+methodName+'.'+#id")
    public String getBook(int id) {
        System.out.println("Method executed..");
        if (id == 1) {
            return "Book 1";
        } else {
            return "Book 2";
        }
    }

b)除了使用key指定外,Spring还提供了org.springframework.cache.interceptor.KeyGenerator接口,使用keyGenerator去指定实现此接口的bean的名字

@Cacheable(cacheNames="sampleCache", keyGenerator="myKeyGenerator")

3.注意@Cacheable配置多个cache时需要在CacheManager中同样注册对应cache,否则包错 Cannot find cache named 'sampleCacheXXX'

 

@Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("sampleCache"),new ConcurrentMapCache("sampleCache2")));
        return cacheManager;
    }

3.cacheManager 指定缓存管理器

应用程序使用多个缓存管理器,去设置cacheManager给每个操作使用

@Cacheable(cacheNames="books", cacheManager="anotherCacheManager")

4.condition : 指定发生条件

@Cacheable(condition="#id >5")  参数id 大于5时加入缓存

 

cache配置类

package com.learn.frame.spring.cache;

import java.util.Arrays;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * spring cache 缓存的使用
 * @author Administrator
 *
 */
@Configuration
@EnableCaching
public class CachingConfig {
    @Bean
    public Book book() {
        return new Book();
    }
	
    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("sampleCache")));//注册名为sampleCache的缓存
        return cacheManager;
    }


	public static void main(String[] args) {
             AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 
            ctx.register(CachingConfig.class);
            ctx.refresh();
            Book book = ctx.getBean(Book.class);        
            // calling getBook method first time.
            System.out.println(book.getBook(1));
            // calling getBook method second time. This time, method will not
            // execute.
            System.out.println(book.getBook(1));
            // calling getBook method third time with different value.
            System.out.println(book.getBook(2));
            ctx.close();
	}
}

 

@EnableCaching注解是spring framework中的注解驱动的缓存管理功能。自spring版本3.1起加入了该注解。如果你使用了这个注解,那么你就不需要在XML文件中配置cache manager了,等价于 <cache:annotation-driven/> 。能够在服务类方法上标注@Cacheable

 

CacheManager : 管理Cache对象

Cache : 用合适的数据结构存储数据(上述例子使用ConcurrentMapCache map结构存储数据对象)

上面的java config和下面的xml配置文件是等效的

<beans>
     <cache:annotation-driven/>
     <bean id="book" class="Book"/>
     <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
         <property name="caches">
             <set>
                 <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
                     <property name="name" value="sampleCache"/>
                 </bean>
             </set>
         </property>
     </bean>
 </beans>

 

定义了一个缓存管理器SimpleCacheManager 并设置名称为sampleCache的缓存,@Cachable的value属性要和此对应。

 

测试输出结果

Method executed..
Book 1
Book 1
Method executed..
Book 2

拓展:我们可以使用redis来代替Map,将数据缓存到第三方容器(如redis)中   redisson整合Spring 缓存

 

参考 Spring Cache

 

 

 

 

 

 

 

  • 8
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值