SpringCache

1.原理图

2.SpringCache缓存实现(此项目是通过mybatis-ssm项目复制得来的)

(1).创建一个spring-cache.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:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/cache
    http://www.springframework.org/schema/cache/spring-cache.xsd"> <cache:annotation-driven cache-manager="cacheManager"/><!--需要启用SpringCache--> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"><!--id="news"就是在业务层里面进行缓存具体操作时使用的名称--> <bean id="news" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"/> </property> </bean> </beans>

 (2).如果要想让缓存配置生效。则一定要在spring-base.xml配置文件里面追加配置项

<import resource="spring-cache.xml"/><!--将cache配置文件导入spring-base.xml配置文件即可-->

 (3).修改业务层接口。这里以INewsService接口为例

public interface INewsService{//下面的news就是上面的那个"id="news""
    @Cacheable(cacheNames="news")//调用此方法就会触发id缓存
    public News get(long id);或
  @Cacheable(cacheNames = "news",condition = "#id<10",unless = "#result==null" )//调用此方法id<10就会触发id缓存,id>10则不再触发缓存
  public News get(long id) ;
  @Cacheable(cacheNames = "news",key = "#id")//此时会认为这两个参数同时满足的时候才会进行缓存数据的加载(此时如果没有设置"key",那么就表示
  缓存的key就是两个参数的整合),但是很多时候未必对所有的参数都需要设置缓存,所以在注解里面加了一个key的属性对缓存做出了一个标记。定义key之后,在其
  它的查询方法里面,只要根据id进行查询的时候都会触发此缓存。
   public News get(long id,String title);
   @Cacheable(cacheNames = "news",key = "#id",sync = true)//"sync"为同步标记,此时由于配置了"sync"属性,所以在进行并发访问的时候
   只会由一个线程负责缓存数据的添加
   public News get(long id,String title);
}

3.缓存更新

1.缓存更新用@CachePut注解控制
2.因为每次注解之前都要注解cacheNames="news",也可以在接口类上面直接使用@CacheConfig(cacheNames="news")进行了缓存信息的统一配置处理
3.@CachePut(key="#vo.nid",unless="#result==null")
  public News update(News vo);//一定要返回新的News对象实例

4.缓存清除

缓存清除用  @CacheEvict
      public boolean delete(long id);

5.多级缓存如果既想保存id的缓存又想保存title的缓存,这样操作的前提是这两个字段都没有重复的数据内容

@Cacheable(unless="#result==null")
public News get(long id);

@Cacheable(unless="#result==null")
public News get(String title);

修改两个参数的get()方法定义,在此操作之中使用多级缓存设置(当前的操作表示对id和title都进行缓存设置):
@Cacheable(cacheable={
   @Cacheable(key="#id"),   @Cacheable(key="#title")  })
public News get(long id,String title);

在进行缓存更新的时候也可以使用多级缓存设置
@Cacheable(put={
   @Cacheput(key="#vo.nid",unless="#result==null")
   @Cacheput(key="#vo.title",unless="#result==null")
 })
public News update(News vo);

说明:在上面的SpringCache都是基于ConcurrentHashMap的操作实现的,但是这样的操作只是在java层次上的实现,而从行业之内使用比较广泛的缓存有两类组件:单机缓存组件(EHCache)和分布式缓存组件(Redis)。

6.SpringCache整合EhCache缓存组件

(1).导入依赖包

<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.6</version>
</dependency>

(2).在"src/main/resources/"目录下创建一个ehcache.xml配置文件

<?xml version="1.1" encoding="UTF-8"?>
<ehcache name="springcache"> 随意定义的缓存的管理名称
    <diskStore path="java.io.tmpdir"/>磁盘上的临时存储路径(环境属性)
    <defaultCache                        定义默认的最多的元素个数
              maxElementsInMemory="2000" 允许缓存的最多的元素个数
              eternal="true"                          允许缓存的内容自动失效
              timeToIdleSeconds="120"          设置缓存的失效时间
              timeToLiveSeconds="120"          设置缓存的存活时间
              overflowDisk="true"/>              当内存不足时,允许将缓存写入到磁盘
    
      <cache name="news"
               maxElementsInMemory="2000"     允许缓存的最多的元素个数
               eternal="false"                      允许缓存的内容自动失效
               timeToIdleSeconds="300"          设置缓存的失效时间
               timeToLiveSeconds="0"          设置缓存的存活时间
               overflowDisk="true"/>              当内存不足时,允许将缓存写入到磁盘
     < /cache>
/ehcache> 

(3).如果想使用ehcache缓存组件就必须在spring-cache.xml配置文件中进行缓存的相关定义

  <cache:annotation-driven cache-manager="cacheManager"/> <!-- 需要启用SpringCache -->
  <bean id="cacheManagerFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="classpath:ehcache.xml"/><!--配置文件-->
  </bean>
  <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" >
    <property name="eacheManager" ref="cacheManagerFactoryBean"/>
  </bean>

注:这个时候只需要修改当前的配置文件,就可以实现项目之中的缓存管理组件的更换。

7.整合Redis分布式缓存

• 在模块之中引入lettuce,springdataredis,commons-pool2等相关的依赖库

• 在src/main/profiles/dev/config/redis.properties配置文件,dev为源代码目录。

redis.host=redis-server//redis数据库连接的主机名称或ip地址
redis.port=6379 //连接端口
redis.auth=hellolee   //认证信息
redis.database=0  //数据库的索引编号
redis.pool.maxTotal=10  //连接池最大的总连接数量
redis.pool.maxIdle=5   //连接池维持的最大连接数量
redis.pool.minIdle=3  //连接池维持的最小的连接数量
redis.pool.testOnBorrow=true  //所有的连接测试后返回

• 由于Lettuce组件需要基于构建模式进行代码的实现,所以本次直接利用配置类的形式进行Redis的连接配置,在这个配置里面重点的配置项在与使用的"RedisTemplate<String,Object>";

• 修改spring-base.xml配置文件,追加新的扫描路径:<context:component-scan base-package="com.yootk.ssm.service,com.yootk.ssm.dao,com.yootk.ssm.config"/>

• 在SpringCache之中并没有提供专属的Redis缓存实现,所以开发者需要自行进行Redis的缓存的具体操作,而这个具体的操作一定要实现Cache接口。

   @Bean("redisTemplate")//将原来的getRedisTempalate方法改成现在这个
   public RedisTemplate getRedisTempalate(
           @Autowired RedisConnectionFactory connectionFactory
   ) {
       RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>() ;
       redisTemplate.setConnectionFactory(connectionFactory);
       redisTemplate.setKeySerializer(new StringRedisSerializer()); // 数据的key通过字符串存储
       redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); // 保存的value为对象
       redisTemplate.setHashKeySerializer(new StringRedisSerializer()); // 数据的key通过字符串存储
       redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); // 保存的value为对象
       return redisTemplate ;
   }

• 修改spring-cache.xml配置文件,使用新的RedisCache进行缓存管理。

 <cache:annotation-driven cache-manager="cacheManager"/> <!-- 需要启用SpringCache -->
  <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
    <property name="caches" ><!--配置文件-->
           <set>
             < bean class="com.yootk.cache.RedisCache" >
               <property name="name" ref="news"/>
                  <property name="redisTemplate" ref="redisTemplate"/>
             </bean>
                  </set>
      </property>
  </bean>

注:这个时候只需要修改当前的配置文件,就可以实现项目之中的缓存管理组件的更换。

  在实际开发之中,这样的缓存的管理机制是当今项目所推荐采用的形式。

  

原文地址:https://www.cnblogs.com/wxl123/p/11094644.html