Spring cache 缓存

spring3.1上的版本可以使用spring注解缓存,配置非常简单:

在对应的spring配置xml文件中添加如下红色配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ss="http://www.springframework.org/schema/security"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" <span style="color:#ff0000;">xmlns:cache="http://www.springframework.org/schema/cache"</span>
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   	http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
   	http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
   	http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
   	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
   	<span style="color:#ff0000;">http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd</span>
   	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><pre name="code" class="java"> <!-- 缓存配置 -->  
    <!-- 启用缓存注解功能(请将其配置在Spring主配置文件中) -->  
    <cache:annotation-driven cache-manager="cacheManager"/>  
    <!-- Spring自己的基于java.util.concurrent.ConcurrentHashMap实现的缓存管理器(该功能是从Spring3.1开始提供的) -->  
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">  
        <property name="caches">  
            <set>  
                <bean name="myCache" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"/>  
            </set>  
        </property>  
    </bean>  

 这样配置就ok了,我们就可以在对应的service层中使用注解来缓存数据了: 

 @Override
    @Cacheable(value="myCache", key="#gwId")   
    public List<Map<String, Object>> queryRecentOperateJobInfo(String gwId) {
        LOGGER.debug("调用缓存测试------------------------------------------");
        LOGGER.debug("do GwIndexServiceImpl queryRecentOperateJobInfo function....");
        // 查询数据库
        return dalClient.queryForList("T_MY_HOMEPAGEOFGW_INFO.SELECT_RECENTOPERATEJOB_BY_FIELDS", paramMap);
}
在我们的接口中,完全没有对应缓存的逻辑代码。当我们查询数据时,spring会通过注解中的key去查看是否会有缓存,如果有缓存,直接从缓存中获取数据,不掉用方法;如果没有缓存过,则调用方法,从数据库中查询数据,并把查询的数据存放在缓存中。


但是还是会有个问题:如果数据更新后,如何处理呢?缓存的删除又改怎么进行?

这里就需要说说spring的3个缓存注解:

@Cacheable、@CachePut、@CacheEvict 


引用网上参考的一张图片:

表 1. @Cacheable 作用和配置方法
@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@Cacheable 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
表 2. @CachePut 作用和配置方法
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@CachePut 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
表 3. @CacheEvict 作用和配置方法
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheEvict 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@CachEvict(value=”mycache”) 或者 
@CachEvict(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@CachEvict(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 例如:
@CachEvict(value=”testcache”,
condition=”#userName.length()>2”)
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 例如:
@CachEvict(value=”testcache”,beforeInvocation=true)
缓存的更新,直接拷贝一段比较直观的代码:

AccountService.java
 @Cacheable(value="accountCache")// 使用了一个缓存名叫 accountCache 
 public Account getAccountByName(String userName) { 
   // 方法内部实现不考虑缓存逻辑,直接实现业务
   return getFromDB(userName); 
 } 
 @CachePut(value="accountCache",key="#account.getName()")// 更新 accountCache 缓存
 public Account updateAccount(Account account) { 
   return updateDB(account); 
 } 
 private Account updateDB(Account account) { 
   System.out.println("real updating db..."+account.getName()); 
   return account; 
 }

 test.java
 
public static void main(String[] args) { 
   ApplicationContext context = new ClassPathXmlApplicationContext( 
      "spring-cache-anno.xml");// 加载 spring 配置文件
  
   AccountService s = (AccountService) context.getBean("accountServiceBean"); 
  
   Account account = s.getAccountByName("someone"); 
   account.setPassword("123"); 
   s.updateAccount(account); 
   account.setPassword("321"); 
   s.updateAccount(account); 
   account = s.getAccountByName("someone"); 
   System.out.println(account.getPassword()); 
 }

如果有多个参数,如何进行 key 的组合

假设 AccountService 现在有一个需求,要求根据账号名、密码和是否发送日志查询账号信息,很明显,这里我们需要根据账号名、密码对账号对象进行缓存,而第三个参数“是否发送日志”对缓存没有任何影响。所以,我们可以利用 SpEL 表达式对缓存 key 进行设计

AccountService.java(支持组合 key)
 @Cacheable(value="accountCache",key="#userName.concat(#password)") 
 public Account getAccount(String userName,String password,boolean sendLog) { 
   // 方法内部实现不考虑缓存逻辑,直接实现业务
   return getFromDB(userName,password); 
  
 }

注意上面的 key 属性,其中引用了方法的两个参数 userName 和 password,而 sendLog 属性没有考虑,因为其对缓存没有影响。


参考文章链接:点击打开链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值