版权声明:如果喜欢,欢迎转载,转载请标明出处。 https://blog.csdn.net/qq_34677946/article/details/81912433
目录
一、为何使用注解方式的redis
代码无侵入,便于修改和维护。
二、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
三、配置文件
#redis
spring:
redis:
host: 118.24.50.160
port: 6379
jedis:
pool:
max-active: 8
max-idle: 8
min-idle: 0
database: 0
四、配置redis
配置完成后在web层使用@Cacheble @Cacheput @Cachevit使用
@Cacheable(cacheNames = {"user"}, key = "#result.uid", condition = "#uid != ''",
unless = "#result.password != null")
cacheNames指定缓存组的名字,存入redis后 缓存组::key,如 "user::123"
key 使用spel表达式, alt+/会有自动提示功能, #result表示方式返回的结果,uid表示结果的某个属性
condition 表示条件成立才会缓存,unless也是。不同的是condition在进入方法时运行。unless在方法结束时运行
@CachePut(cacheNames = {"user"}, keyGenerator = "keyGenerator")
CachePut同样是存入redis不同于cachaeble的是,前者每次都会将结果存入redis。后者会先到redis查询
key的值,若存在值,则不再运行方法,直接返回redis的值。
@CacheEvict(cacheNames = {"user"},key = "#result.uid")
CacheEvit 删除缓存组里面的某个key值。
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import java.lang.reflect.Method;
import java.net.UnknownHostException;
/**
* redis配置类
*
* @see RedisAutoConfiguration
* @author pjj
*/
@Slf4j
@Configuration
public class RedisConfig {
//RedisTemplate 不存在是才会自动创建、改造原创建方法
@Bean
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<String, Object> template = new RedisTemplate<String,Object>();
template.setConnectionFactory(redisConnectionFactory);
// 使用Jackson2JsonRedisSerialize 替换默认序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 设置value的序列化规则和 key的序列化规则
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
@Bean
public KeyGenerator keyGenerator() {
KeyGenerator keyGenerator = new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuilder sb = new StringBuilder();
String className = o.getClass().getName();
String methodName = method.getName();
sb.append(className).append("->").append(methodName);
for (Object obj : objects) {
sb.append("_").append(o.toString());
}
String key = sb.toString();
log.info("===> 生成的key为 {}", key);
return key;
}
};
return keyGenerator;
}
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
/**
* 项目启动执行
*
* @author pjj
*/
@Slf4j
@Configuration
public class RedisRunner implements CommandLineRunner{
@Autowired
private RedisTemplate redisTemplate;
@Override
public void run(String... args) throws Exception {
log.info("===> value key序列化方式为 {}", redisTemplate.getKeySerializer());
log.info("===> value value序列化方式为 {}", redisTemplate.getValueSerializer());
log.info("===> hash key 序列化方式为 {}", redisTemplate.getHashKeySerializer());
log.info("===> hash value 序列化方式为 {}", redisTemplate.getHashValueSerializer());
}
}
五、集群配置
只需要加入下面属性即可,spring-boot-starter-data-redis 默认注入了RedisProperties,在启动时会自动加载redis集群和哨兵模式。其他的都不用变。
#redis
spring:
redis:
jedis:
pool:
max-active: 8
max-idle: 8
min-idle: 0
database: 0
cluster:
nodes: 192.168.0.101:6379,192.168.0.102:6379,192.168.0.103:6379,
@ConfigurationProperties(
prefix = "spring.redis"
)
public class RedisProperties {
private int database = 0;
private String url;
private String host = "localhost";
private String password;
private int port = 6379;
private boolean ssl;
private Duration timeout;
private RedisProperties.Sentinel sentinel;
private RedisProperties.Cluster cluster;
private final RedisProperties.Jedis jedis = new RedisProperties.Jedis();
private final RedisProperties.Lettuce lettuce = new RedisProperties.Lettuce();
.......
.......
}
@Configuration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}