Spring Cache注解

本文介绍Spring 3.1中新增的缓存注解功能,包括@Cacheable和@CacheEvict的使用方法及参数详解。通过示例展示了如何配置Spring缓存及EHCache集成。

需要感慨一下,spring3.0时丢弃了2.5时的spring-modules-cache.jar,致使无法使用spring来方便的管理cache注解,好在3.1.M1中增加了对cache注解的支持,可喜可贺啊!

 

希望了解spring2.5的cache注解,可以参考如下内容:

Spring基于注解的缓存配置--EHCache AND OSCache

Spring基于注解的缓存配置--web应用实例

2.5时,spring没有自己的解决方案,都是采用对许多第三方cache框架的支持,比如EHCache和OSCache等等,不过到了3.1,spring就只提供EHCache的支持了,不过spring3.1还给出了自己的解决方案。

 

下面简单介绍一下spring3.1.M1中的cache功能。

spring3.1.M1中负责cache的模块是org.springframework.context-3.1.0.M1.jar

 

与2.5时的modules模块类似,3.1的注解缓存也是在方法上声明注解,3.1同样提供了两个注解:

@Cacheable:负责将方法的返回值加入到缓存中

@CacheEvict:负责清除缓存

 

@Cacheable 支持如下几个参数:

value:缓存位置名称,不能为空,如果使用EHCache,就是ehcache.xml中声明的cache的name

key:缓存的key,默认为空,既表示使用方法的参数类型及参数值作为key,支持SpEL

condition:触发条件,只有满足条件的情况才会加入缓存,默认为空,既表示全部都加入缓存,支持SpEL

 

例如:

Java代码   收藏代码
  1. //将缓存保存进andCache,并使用参数中的userId加上一个字符串(这里使用方法名称)作为缓存的key   
  2. @Cacheable(value="andCache",key="#userId + 'findById'")  
  3. public SystemUser findById(String userId) {  
  4.     SystemUser user = (SystemUser) dao.findById(SystemUser.class, userId);        
  5.     return user ;         
  6. }  
  7. //将缓存保存进andCache,并当参数userId的长度小于32时才保存进缓存,默认使用参数值及类型作为缓存的key  
  8. @Cacheable(value="andCache",condition="#userId.length < 32")  
  9. public boolean isReserved(String userId) {  
  10.     System.out.println("hello andCache"+userId);  
  11.     return false;  
  12. }  

 

 

@CacheEvict 支持如下几个参数:

value:缓存位置名称,不能为空,同上

key:缓存的key,默认为空,同上

condition:触发条件,只有满足条件的情况才会清除缓存,默认为空,支持SpEL

allEntries:true表示清除value中的全部缓存,默认为false

 

例如:

Java代码   收藏代码
  1. //清除掉指定key的缓存  
  2. @CacheEvict(value="andCache",key="#user.userId + 'findById'")  
  3. public void modifyUserRole(SystemUser user) {  
  4.          System.out.println("hello andCache delete"+user.getUserId());  
  5. }  
  6.   
  7. //清除掉全部缓存  
  8. @CacheEvict(value="andCache",allEntries=true)  
  9. public void setReservedUsers() {  
  10.     System.out.println("hello andCache deleteall");  
  11. }  

 

一般来说,我们的更新操作只需要刷新缓存中某一个值,所以定义缓存的key值的方式就很重要,最好是能够唯一,因为这样可以准确的清除掉特定的缓存,而不会影响到其它缓存值

比如我这里针对用户的操作,使用(userId+方法名称)的方式设定key值当然,你也可以找到更适合自己的方式去设定。

 

SpEL:Spring Expression Language

关于SpEL的介绍,可以参考如下地址:

http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/expressions.html

 

 

了解了cache的注解之后,接下来说说如何使注解生效,其实就是需要在spring的配置文件中增加一些配置。

 

1.spring-cache

首先我们来看一下如何使用spring3.1自己的cache,

需要在命名空间中增加cache的配置

Xml代码   收藏代码
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  3.      xmlns:cache="http://www.springframework.org/schema/cache"  
  4.     xsi:schemaLocation="  
  5.             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
  6.             http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">  

 

之后添加如下声明:

Xml代码   收藏代码
  1.       <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->  
  2. <cache:annotation-driven cache-manager="cacheManager"/>  
  3.   
  4.   
  5. <!-- spring自己的换管理器,这里定义了两个缓存位置名称 ,既注解中的value -->  
  6. <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">  
  7.     <property name="caches">  
  8.         <set>  
  9.             <bean  
  10.                 class="org.springframework.cache.concurrent.ConcurrentCacheFactoryBean"  
  11.                 p:name="default" />  
  12.             <bean  
  13.                 class="org.springframework.cache.concurrent.ConcurrentCacheFactoryBean"  
  14.                 p:name="andCache" />  
  15.         </set>  
  16.     </property>  
  17. </bean>   

 

2.spring-ehcache

接下来说说对ehcache的支持,其实只需要把cacheManager换成EHCache的cacheManager即可,如下:

Xml代码   收藏代码
  1.        <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->  
  2. <cache:annotation-driven cache-manager="cacheManager"/>  
  3.   
  4. <!-- cacheManager工厂类,指定ehcache.xml的位置 -->   
  5. <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"   
  6.     p:configLocation="classpath:/config/ehcache.xml" />   
  7.   
  8. <!-- 声明cacheManager -->  
  9. <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"   
  10.     p:cacheManager-ref="cacheManagerFactory" />  

 

 

 ehcache.xml

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"  
  4.     monitoring="autodetect">  
  5.     <!--  
  6.     <diskStore path="java.io.tmpdir" /> -->  
  7.     <diskStore path="E:/cachetmpdir"/>  
  8.     <defaultCache maxElementsInMemory="10000" eternal="false"  
  9.         timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"  
  10.         maxElementsOnDisk="10000000" diskPersistent="false"  
  11.         diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />  
  12.           
  13.     <cache name="andCache" maxElementsInMemory="10000"  
  14.         maxElementsOnDisk="1000" eternal="false" overflowToDisk="true"  
  15.         diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600"  
  16.         memoryStoreEvictionPolicy="LFU" />  
  17. </ehcache>    

 

 

ok,这样注解缓存就生效了。

 

 附件中是我自己写的一个小例子,工程结构如下所示,运行com.piaoyi.function.demo下的DemoTest即可

 

参考资料:

http://blog.springsource.com/2011/02/23/spring-3-1-m1-caching/

http://hi.baidu.com/coolcooldool/blog/item/3b541533c72b40e21a4cffda.html

 

### Spring Cache 注解详解:含义与使用方法 Spring CacheSpring 框架中用于简化缓存管理的模块,通过注解的方式实现对缓存的声明式控制。开发者可以利用这些注解在不侵入业务逻辑的情况下实现缓存的读取、更新和删除操作。 #### `@Cacheable` 注解注解用于标记一个方法的结果需要被缓存。当方法被调用时,Spring 会先检查缓存中是否存在对应的数据,如果存在则直接返回缓存结果,否则执行方法并将结果放入缓存中。可以通过 `cacheNames` 或 `value` 属性指定缓存名称,通过 `key` 属性定义缓存键值。 示例: ```java @Cacheable(cacheNames = "users", key = "#id") public User getUserById(Long id) { return userRepository.findById(id); } ``` 上述代码表示每次调用 `getUserById` 方法时,Spring 会根据 `id` 构建缓存键,并尝试从名为 `users` 的缓存中获取数据[^2]。 #### `@CachePut` 注解注解用于更新缓存中的数据,无论缓存中是否存在旧数据,都会将方法的返回值写入缓存。通常用于更新操作,确保缓存中的数据始终是最新的。 示例: ```java @CachePut(cacheNames = "users", key = "#user.id") public User updateUser(User user) { return userRepository.save(user); } ``` 该方法在执行后会将更新后的用户对象存储到 `users` 缓存中,确保缓存与数据库同步[^5]。 #### `@CacheEvict` 注解注解用于清除缓存中的数据。可以用于删除单个条目或清空整个缓存区域。常用于删除操作之后,避免缓存中保留无效数据。 示例: ```java @CacheEvict(cacheNames = "users", key = "#id") public void deleteUserById(Long id) { userRepository.deleteById(id); } ``` 此方法会在删除用户后,从 `users` 缓存中移除对应的用户信息[^5]。 #### `@Caching` 注解注解允许在一个方法或类上同时指定多个缓存操作,包括 `cacheable`、`put` 和 `evict`。它适用于复杂的缓存需求,例如在同一方法上同时进行缓存读取、更新和删除操作。 示例: ```java @Caching( cacheable = @Cacheable("role"), evict = { @CacheEvict("role2"), @CacheEvict(value = "role", allEntries = true) }, put = { @CachePut(value = "role", key = "#role.id"), @CachePut(value = "role", key = "#role.name"), @CachePut(value = "role", key = "#role.account") } ) public Role find(Role role) { return null; } ``` 该方法展示了如何在一个方法上组合使用多种缓存操作,以满足更复杂的缓存逻辑需求[^5]。 #### 缓存命名空间与切面支持 除了基本的注解功能外,Spring Cache 还支持通过自定义切面(Aspect)来增强缓存行为。例如,可以在切面类中定义前置通知(`@Before`)来实现更细粒度的缓存控制逻辑。 示例: ```java @Aspect @Component @CacheAspect public class CacheAspectForProductService { @Before("@cacheableMethod execution(* com.example.product.ProductService.get*(..))") public void cacheBeforeAdvice(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); String methodName = joinPoint.getSignature().getName(); String cacheKey = methodName + ":" + Arrays.toString(args); // 这里可以添加缓存检查和缓存填充逻辑 } } ``` 此切面类会在调用 `ProductService` 中所有以 `get` 开头的方法前执行缓存检查逻辑,进一步提升缓存的灵活性和可扩展性[^3]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值