Spring Boot中使用缓存Redis、EhCache

缓存相信各位同学都或多或少用到过,毕竟不能把所有压力都给数据库。今天来简单总结一下下在Spring Boot中使用Redis和EhCache缓存O(∩_∩)O~
Spring Boot本身是支持多种缓存实现的,其中提供了4个注解来帮助大家使用缓存:

  • @EnableCaching 开启缓存支持
  • @Cacheable 先检查缓存是否存在,若存在,则直接返回缓存中结果;若不存在,则执行方法获取结果,并将结果放到缓存中
  • @CacheEvict 清除缓存
  • @CachePut 始终执行方法,并将结果放到缓存中

先说一下EhCache,EhCache是在内存中的缓存,也就是说,程序在,缓存就在,程序停了,缓存就没了,要使用EhCache,首先引入pom starter:

	
			org.springframework.boot
			spring-boot-starter-cache
	

在启动类上开启缓存支持:

@SpringBootApplication
@EnableCaching
public class Application {
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

下来只需要在方法上加上注解就行了:

@Cacheable(value="user",key = "#user.id")
public User findOne(User user) {
      User u=userRepository.findOne(user.getId());
      return u;
}

可以看到,在注解中指定了value和key两个参数,value是用来归类用的,以上方法所生成的所有缓存在缓存库中都存放在user文件夹下;key是用来指定缓存键值的,它有两种生成策略——默认策略和自定义策略,其默认策略如下:

  • 如果方法没有参数,则使用0作为key
  • 如果只有一个参数,则使用该参数作为key
  • 如果参数多于一个,则使用所有参数的hashCode作为key

很明显,我这里自定义了key,指定为参数user对象的id。
key支持通过Sping EL表达式来指定,几个一看就懂的栗子:

   @Cacheable(value="user", key="#id")
   public User find(Integer id) {
      return null;
   }
   
   @Cacheable(value="user", key="#p0")
   public User find(Integer id) {
      return null;
   }

   @Cacheable(value="user", key="#user.id")
   public User find(User user) {
      return null;
   }

   @Cacheable(value="user", key="#p0.id")
   public User find(User user) {
      return null;
   }

除了上述使用方法参数生成key以外,Spring还提供了一个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

另外,如果EhCache有别的设置,那么可以新建一个ehcache.xml,在application.properties中配好这个配置文件即可:

spring.cache.type=ehcache
spring.cache.ehcache.config=static/ehcache.xml

下面说一下Redis,同样首先引入pom starter:


		org.springframework.boot
		spring-boot-starter-data-redis

同样通过@EnableCaching打开缓存支持。

由于Redis是独立安装的,它就像数据库一样可以持久化数据,所以必然也像数据库一样有连接地址,在application.yml中配置如下:

	spring:
	  redis:
	    database: 0
	    host: 10.155.20.162
	    port: 6379
	    pool:
	      max-active: 80
	      max-wait: -1
	      max-idle: 80
	      min-idle: 0
	    timeout: 5000

呐,EhCache的时候用的properties配置文件,Redis用的yml配置文件哟,各取所爱吧~

同样在方法上面使用@Cacheable、@CacheEvict、@CachePut来操作缓存。
这里介绍一下keyGenerator,前面key的生成策略就是它控制的,Spring允许我们自定义这个Generator,举个栗子:

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport{
    //自定义key生成方式
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                String[] value = new String[1];
                Cacheable cacheable = method.getAnnotation(Cacheable.class);
                if (cacheable != null) {
                    value = cacheable.value();
                }
                CachePut cachePut = method.getAnnotation(CachePut.class);
                if (cachePut != null) {
                    value = cachePut.value();
                }
                CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class);
                if (cacheEvict != null) {
                    value = cacheEvict.value();
                }
                sb.append(value[0]);
                sb.append(":");
                sb.append(params[0].toString());
                return sb.toString();
            }
        };
    }

    //缓存管理器
    @Bean
    public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setDefaultExpiration(43200);  //设置缓存过期时间
        return cacheManager;
    }
    
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory){
        StringRedisTemplate template = new StringRedisTemplate(factory);
        @SuppressWarnings({ "rawtypes", "unchecked" })
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

可以看到,这个Config中有3个Bean,第1个Bean中用注解的value属性+":"+第一个参数作为key值的生成策略;第2个Bean中指定了缓存的全局过期时间;第3个Bean中定义了RedisTemplate。

ok,以上讲了通过注解来操作缓存,不过有的时候,并不一定存在方法,只是单纯地想操作某个key值的缓存,咋办?这个时候就要用到RedisTemplate啦,Spring中自带这个对象,包括上面也自定义了这个对象,我们在需要使用的地方把它注入进来就可以了。不过,通常我们会先写个工具类:

@Service
public class RedisService {
    @Autowired
    @Qualifier("stringRedisTemplate")
    RedisTemplate template;

    public void setValue(String key, Object val) {
        template.opsForValue().set(key, val);
    }

    public void setValue(String key, Object val, int time, TimeUnit unit) {
        template.opsForValue().set(key, val, time, unit);
    }

    public Object getValue(String key) {
        return template.opsForValue().get(key);
    }

    public void deleteValue(String key){
        template.delete(key);
    }
}

可以看到,我这边使用的是stringRedisTemplate,具体还有什么其它类型,各位同学自己去发现一以下吧~

你可能感兴趣的:(Java)