相比于Spring来说,在SpringBoot中使用Redis大幅简化了。通过使用spring-boot-starter-data-redis
,使用Redis变得非常简单。
基本步骤如下:
- 添加依赖
1<dependency>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-data-redis</artifactId>
4</dependency>
- 配置application.properties/yaml
1spring:
2 redis:
3 host: 192.168.2.230
4 port: 6379
5 password: xxxxxx
6 database: 1
7 timeout: 3000ms
- 注入RedisTemplate使用
1 @Autowired
2 StringRedisTemplate stringRedisTemplate;
就是这么简单。
1. Redis自动注册
刚开始使用spring-boot-starter-data-redis
的时候很奇怪在propertySource中的配置参数(spring.redis.*)是怎么起作用的?
最初怀疑是在包spring-boot-starter-data-redis
中,但是查看源码发现这个包没有任何源码,只是一个pom文件,提供了对:spring-data-redis、jedis的依赖。
后来有怀疑是不是在spring-data-redis包中。上Github中看源码也没有。
最后才发现原来是在Spring-boot中的spring-boot-autoconfigure
这个包里面的RedisAutoConfiguration
这个类中。
1@Configuration
2@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
3@EnableConfigurationProperties(RedisProperties.class)
4public class RedisAutoConfiguration {
5 /**
6 * Redis connection configuration.
7 */
8 @Configuration
9 @ConditionalOnClass(GenericObjectPool.class)
10 protected static class RedisConnectionConfiguration { private final RedisProperties properties;
11 public RedisConnectionConfiguration(RedisProperties properties,
12 ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
13 ObjectProvider<RedisClusterConfiguration> clusterConfiguration) {
14 this.properties = properties;
15 this.sentinelConfiguration = sentinelConfiguration.getIfAvailable();
16 this.clusterConfiguration = clusterConfiguration.getIfAvailable();
17 }
18
19 @Bean
20 @ConditionalOnMissingBean(RedisConnectionFactory.class)
21 public JedisConnectionFactory redisConnectionFactory()
22 throws UnknownHostException {
23 return applyProperties(createJedisConnectionFactory());
24 }
25
26 // 根据参数情况决定创建那种类型的Factory:可以是Cluster、Sentinel或者普通模式。
27 private JedisConnectionFactory createJedisConnectionFactory() {
28 JedisPoolConfig poolConfig = this.properties.getPool() != null
29 ? jedisPoolConfig() : new JedisPoolConfig();
30
31 if (getSentinelConfig() != null) {
32 return new JedisConnectionFactory(getSentinelConfig(), poolConfig);
33 }
34 if (getClusterConfiguration() != null) {
35 return new JedisConnectionFactory(getClusterConfiguration(), poolConfig);
36 }
37 return new JedisConnectionFactory(poolConfig);
38 }
39 ...
40 }
41 ....
42}
可以看到在AutoConfiguration中大量使用了Condition类型的注解。spring-boot会根据当前类路径上存在的类情况以及Bean是否已经创建的情况决定是否要创建Bean。
上面只是代码的一部分,展示了怎么根据配置创建RedisConnectionFactory
对象。
真正与PropertySource有关的代码在RedisProperties
这个类中:
1/**
2 * Configuration properties for Redis.
3 *
4 * @author Dave Syer
5 * @author Christoph Strobl
6 * @author Eddú Meléndez
7 * @author Marco Aust
8 */
9@ConfigurationProperties(prefix = "spring.redis")
10public class RedisProperties {
11 private int database = 0;
12 private String url;
13 ....
看代码,通过@ConfigurationProperties
这个注解指定了prefix,从而可以从.properties或.yaml类型的配置文件直接读取redis相关的配置参数。
2. 自定义Bean
在RedisAutoConfiguration
中会自动根据参数配置情况决定创建那种redis的链接池。这一点非常方便。可以直接在其他类中使用@Autowired注入:JedisConnectionFactory类型的变量。另外,该类还会自动创建两个Bean:
- RedisTemplate<Object, Object>
- StringRedisTemplate 但是通常情况下这两个Bean不一定能够满足要求(例如其序列化支持方式可能不满足要求),这时可以手动创建者类Bean。像这样:
1@Configuration
2public class RedisConfig {
3
4 @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
5 @Autowired
6 RedisConnectionFactory redisConnectionFactory;
7
8 @Bean(name="redisSerializer")
9 public StringRedisSerializer redisSerializer() {
10 return new StringRedisSerializer();
11 }
12
13 @Bean(name="redisTemplate")
14 public RedisTemplate<String, String> redisTemplate() {
15 RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
16 redisTemplate.setConnectionFactory(redisConnectionFactory);
17 redisTemplate.setDefaultSerializer(redisSerializer());
18 return redisTemplate;
19 }
20}
你可以自己定义Serializer,达到完全的控制。上面只是个例子,实际调用的还是spring-data-redis
中的StringRedisSerializer。
3. 关闭自动注册
当然,如果不需要Spring Boot自动注册这些Bean,可以禁用Redis的AutoConfiguration。比较常见的方式是通过@EnableAutoConfiguration
注解中的exclude
参数来解决,例如:
1@EnableAutoConfiguration(exclude = {RedisAutoConfiguration.class})
更多方法可以参考附录。关闭自动注册以后就可以像以前一样自定义所有的Bean。
4. Intellij报错的问题
RedisAutoConfiguration会自动创建RedisConnectionFactory和RedisTemplate,但是在intellij idea中检测会有问题。只有当@Autowired写到Application类中的时候才不报错。添加到其他@Configuration类中则会报无法autowire错误:
Could not autowire bean 'RedisConnectionFactory'....
。
实际编译的时候不报错,说明是正确的,只是IDE检测的问题。这应该是idea的bug,或者支持还不完善。可以参考附录中的资料。
可以通过注解@SuppressWarnings
这个注解解决这个问题,就如同上面的代码中显示的那样。