先上代码
一 添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- lettuce pool 缓存连接池 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
二 配置文件
spring: datasource: driver-class-name : com.mysql.jdbc.Driver url : jdbc:mysql://10.37.136.161:3306/rdrssit1?&useSSL=false username: fabu password: 73R4_h8td6fE redis: host : 10.37.136.18、 port : 6379 timeout : 1000 lettuce: pool: max-active : 8 max-wait : -1 max-idle : 500 min-idle : 0
三 实现我们的RedisTemplate
@Configuration @AutoConfigureAfter(RedisAutoConfiguration.class) public class RedisCacheAutoConfiguration { @Bean public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) { RedisTemplate<String, Serializable> template = new RedisTemplate<>(); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer());//只有这么写才能传进去对象 template.setConnectionFactory(redisConnectionFactory); return template; } }
@Repository public class RedisDao { @Autowired 通过自动装配的方式就能引用到了 private StringRedisTemplate template; public void setKey(String key,String value){ ValueOperations<String, String> ops = template.opsForValue(); ops.set(key,value,1, TimeUnit.MINUTES);//1分钟过期 } public String getValue(String key){ ValueOperations<String, String> ops = this.template.opsForValue(); return ops.get(key); } }
四 原理
在上面的实现我们自己的RedisTemplate时,注意这个注解@AutoConfigureAfter(RedisAutoConfiguration.class)
先看看 RedisAutoConfiguration
@Configuration @ConditionalOnClass(RedisOperations.class) @EnableConfigurationProperties(RedisProperties.class) @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class }) public class 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; } }
到这里就不得不提下注解 @EnableConfigurationProperties
ConfigurationPropertiesBindingPostProcessor会对标注@ConfigurationProperties注解的Bean进行属性值的配置
注意上面的话,有@ConfigurationProperties的bean,也就是说首先要有一个能被Spring管理的bean,它的@ConfigurationProperties才会被处理
然后 我们再看
@ConfigurationProperties(prefix = "spring.redis") public class RedisProperties
我们发现 RedisProperties没有诸如@Service @Component这种能被Spring识别的注解
那么关键就是 @EnableConfigurationProperties
这个注解要展开就太多了,姑且记得它能让一个class变成bean
这样 RedisProperties 会自动读取yml中的配置信息
回头再看LettuceConnectionConfiguration,这里的RedisProperties properties通过LettuceConnectionConfiguration的构造函数注入进来
@Configuration @ConditionalOnClass(RedisClient.class) class LettuceConnectionConfiguration extends RedisConnectionConfiguration { private final RedisProperties properties; private final List<LettuceClientConfigurationBuilderCustomizer> builderCustomizers; LettuceConnectionConfiguration(RedisProperties properties, ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider, ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider, ObjectProvider<List<LettuceClientConfigurationBuilderCustomizer>> builderCustomizers) { super(properties, sentinelConfigurationProvider, clusterConfigurationProvider); this.properties = properties; this.builderCustomizers = builderCustomizers .getIfAvailable(Collections::emptyList); }
同样这里还有一个方法,通过@Bean把LettuceConnectionFactory 注入到Spring容器里
@Bean @ConditionalOnMissingBean(RedisConnectionFactory.class) public LettuceConnectionFactory redisConnectionFactory( ClientResources clientResources) throws UnknownHostException { LettuceClientConfiguration clientConfig = getLettuceClientConfiguration( clientResources, this.properties.getLettuce().getPool()); return createLettuceConnectionFactory(clientConfig); }
这样我们自己写的 LettuceConnectionFactory就能自动注入进来了
@Configuration @AutoConfigureAfter(RedisAutoConfiguration.class) public class RedisCacheAutoConfiguration { @Bean public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) { RedisTemplate<String, Serializable> template = new RedisTemplate<>(); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer());//只有这么写才能传进去对象 template.setConnectionFactory(redisConnectionFactory); return template; } }