Spring启用缓存

Java框架

浏览数:137

2019-8-22

AD:资源代下载服务

Spring对缓存的支持类似于对事务的支持,Spring缓存的思想是在调用方法时,会把该方法的参数和返回结果作为一个键值对存放于缓存中,下次在调用该方法时直接从缓存返回结果。

Spring支持两种设置方法,注解和xml

1.配置缓存的注解驱动

可以直接创建配置缓存的xml配置文件,或者直接再原spring配置文件中添加,缓存的注解驱动

<cache:annotation-driven/>

创建配值文件如下:

<?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-3.0.xsd

     http://www.springframework.org/schema/cache

     http://www.springframework.org/schema/cache/spring-cache.xsd">
     
     
   <cache:annotation-driven/>
   
   <bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager"/>

</beans>

或者如果spring的配置文件为java,可以直接再类上添加@EnableCaching注解

@Configuration
@EnableCaching
public class CachingConfig{
    @Bean
    public CacheManager cacheManager(){
        return new ConcurrentMapCacheManager();
    }
    
}

<cache:annotation-driven/> 和 @EnableCaching 都是创建了一个切面并触发spring缓存注解的切点,这个切面负责管理缓存

同时除了上面配置的ConcurrentMapCacheManager缓存管理器,spring还提供了许多其他的缓存管理器,如:EhCacheCacheManager,SimpleCacheManager,RedisCacheManager等

使用Redis缓存

RedisCacheManager与Redis服务器协作,通过RedisTemplate将缓存存储到Redis中。

@Configuration
@EnableCaching
public class CachingConfig{
    //缓存管理器bean
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate){
        return new RedisCacheManager(redisTemplate);
    }
    //连接工厂bean
    @Bean
    public JedisConnectionFactory redisConnectionFactory(){
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.afterPropertiesSet()
        return jedisConnectionFactory;
    }
    @Bean
    //redisTemplate 的bean类
    public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory redisCF){
        RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory()
        redisTemplate.afterPropertiesSet()
        return redisTemplate;
    }
}

当然多个缓存管理器之间可以混合使用,返回一个缓存管理的列表即可。

@Configuration
@EnableCaching
public class CachingConfig{
    @Bean
    public CacheManager cacheManager(net.sf.ehcache.CacheManager cm,javax.cache.CacheManager jcm){
        CompositeCacheManager cacheManager = new CompositeCacheManager();
        List<CacheManager> managers = new ArrayList<>();
        managers.add(new JCacheCacheManager(jcm));
        managers.add(new EhcacheCacheManager(cm));
        managers.add(new RedisTemplate(redisTemplate));
        return cacheManager;
    }
    
}

2.为方法添加注解支持缓存

如果注解在方法上,缓存行为只会在方法上,如果注解在类上,缓存行为就会应用到这个类的所有方法上。

  • @Cacheable 在spring调用方法之前,首先应该在缓存中查找方法的返回值,如果无,方法被调用。
@Cacheable可以指定三个属性,value、key和condition。

value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。

@Cacheable("cache1")//Cache是发生在cache1上的
public User find(Integer id) {
     return service.getUserById(id);
}

 @Cacheable({"cache1", "cache2"})//Cache是发生在cache1和cache2上的
public User find(Integer id) {

    return service.getUserById(id);
}

key属性是用来指定Spring缓存方法的返回结果时对应的key的。

@Cacheable(value="users", key="#id")
public User find(Integer id) {

      return service.getUserById(id);
}

可以使用spel语言自动生成key,例如

root.methodName

root.target

id

condition可以指定发生的条件,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。

@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")
public User find(User user) {

      System.out.println("find user by user " + user);

      return user;
}
  • @CachePut
    spring会将方法的返回值放到缓存中,调用前不会检测缓存。

@CachePut 也可以指定三个属性,value、key和condition。

  • @CacheEvict
    spring应该在缓存中清除一个或多个条目。

@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation

allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。

 @CacheEvict(value="users", allEntries=true)

   public void delete(Integer id) {

      System.out.println("delete user by id: " + id);

   }

清除操作默认是在对应方法成功执行之后触发的,使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

@CacheEvict(value="users", beforeInvocation=true)
public void delete(Integer id) {
      System.out.println("delete user by id: " + id);
}
  • @Caching

@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。

@Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),

         @CacheEvict(value = "cache3", allEntries = true) })

public User find(Integer id) {

      return service.getUserById(id);

}

作者:张晓天a