Spring Boot集成Cache和Redis

构建基于Spring Boot 2.X应用,使用Cache,需要引入:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

以前开发Spring用EhCache来做缓存。在做集群或分布式时,还是Redis比较好用。引入Spring Data Redis如下:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

注意这里会有jedis依赖。

在applicatin.yml配置Redis和Cache:

spring:
  cache:
    redis:
      cache-names:
      cache-null-values: false
      key-prefix: spring:cache
      time-to-live: 0
      use-key-prefix: true
    type: # Cache type. By default, auto-detected according to the environment.
  redis:
    database: 5
    url: # Connection URL. Overrides host, port, and password. User is ignored. Example: redis://user:password@example.com:6379
    host: 127.0.0.1
    port: 6379
    password:
    timeout: 3000
    jedis:
      pool:
        max-active: 200
        max-idle: 10
        max-wait: -1
        min-idle: 0

更多配置属性可参考Spring Boot官方说明:

新建RedisConfig类,增加如下方法:

/**
 * 定义缓存数据 key 生成策略的bean
 * 包名+类名+方法名+所有参数
 * @return
 */
@Bean
public KeyGenerator wiselyKeyGenerator(){
	return new KeyGenerator() {
		@Override
		public Object generate(Object target, Method method, Object... params) {
			StringBuilder buff = new StringBuilder();
			buff.append(target.getClass().getName());
			buff.append(method.getName());
			for (Object obj : params) {
				buff.append(obj.toString());
			}
			return buff.toString();
		}
	};
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

	RedisTemplate<String, Object> template = new RedisTemplate<>();
	template.setConnectionFactory(factory);
	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);
	StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
	// key采用String的序列化方式
	template.setKeySerializer(stringRedisSerializer);
	// hash的key也采用String的序列化方式
	template.setHashKeySerializer(stringRedisSerializer);
	// value序列化方式采用jackson
	template.setValueSerializer(jackson2JsonRedisSerializer);
	// hash的value序列化方式采用jackson
	template.setHashValueSerializer(jackson2JsonRedisSerializer);
	template.afterPropertiesSet();

	return template;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {

	RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
	// 设置缓存的默认超时时间:30分钟
	redisCacheConfiguration.entryTtl(Duration.ofMinutes(30L));
	// 如果是空值,不缓存
	redisCacheConfiguration.disableCachingNullValues();
	// 设置key序列化器
	redisCacheConfiguration.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
	// 设置value序列化器
	redisCacheConfiguration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

	RedisCacheManager.RedisCacheManagerBuilder build = RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory));
	RedisCacheManager cacheManager = build.cacheDefaults(redisCacheConfiguration).build();

	return cacheManager;
}

如果需要连接多个Redis,可以用如下方法创建连接:

@Bean
public RedisConnectionFactory  connectionFactory() {

	JedisPoolConfig poolConfig = new JedisPoolConfig();
	poolConfig.setMaxTotal(10);
	poolConfig.setMaxIdle(10);
	poolConfig.setMaxWaitMillis(2000);
	poolConfig.setMinIdle(0);
	poolConfig.setTestOnBorrow(true);
	poolConfig.setTestOnReturn(false);
	poolConfig.setTestWhileIdle(true);
	JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
			.usePooling().poolConfig(poolConfig).and().readTimeout(Duration.ofMillis(3000)).build();

	// 单点redis
	RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
	// 哨兵redis
	// RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration();
	// 集群redis
	// RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
	redisConfig.setHostName("127.0.0.1");
//        redisConfig.setPassword(RedisPassword.of(redisAuth));
	redisConfig.setPort(6379);
	redisConfig.setDatabase(0);

	return new JedisConnectionFactory(redisConfig,clientConfig);
}

需要注意的是,当系统有多个RedisConnectionFactory时,需要指定一个主Bean,指定Bean名称,创建对象方法上加上@Primary注解。在自动注入时,使用@Qualifier指定注入的Bean。

Spring Cache使用很简单,主要以下几个注解:

@Cacheable:声名在方法上。方法第一次被调用后数据将缓存起来,下次调用从缓存中读取。

@CachePut:声名在方法上。方法被调用时数据会缓存起来,但不会从缓存中读取。适合更新缓存。

@CacheEvict:清除缓存。可指定要清除的key。

@CacheConfig:可以声名在类名上,设置缓存。

这些注解可以用很多参数,还支持key表达式。使用方法可以参考:https://blog.csdn.net/dreamhai/article/details/80642010

留下评论

电子邮件地址不会被公开。