执子之手

与子偕老


  • 首页

  • 分类

  • 归档

  • 标签

  • 关于

  • 搜索
close

迁移到SpringBoot 04 - Redis

时间: 2018-05-24   |   分类: 开发     |   阅读: 1963 字 ~4分钟   |   访问: 0

相比于Spring来说,在SpringBoot中使用Redis大幅简化了。通过使用spring-boot-starter-data-redis,使用Redis变得非常简单。

基本步骤如下:

  1. 添加依赖
1<dependency>
2    <groupId>org.springframework.boot</groupId>
3    <artifactId>spring-boot-starter-data-redis</artifactId>
4</dependency>
  1. 配置application.properties/yaml
1spring:
2  redis:
3    host: 192.168.2.230
4    port: 6379
5    password: xxxxxx
6    database: 1
7    timeout: 3000ms
  1. 注入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这个注解解决这个问题,就如同上面的代码中显示的那样。

附录、参考资料

  • Autowiring for Bean Class inspection in Spring Boot project
  • Disabling Redis Auto-configuration in Spring Boot applications
  • Spring Data Redis示例
  • Spring Boot学习之旅:(六)springboot 整合 redis 以及 redis 通用工具类
  • spring-data-redis注册fastjson序列化工具
  • redis-10-spring-boot
  • 如何使用RedisTemplate访问Redis数据结构
#Spring# #Springboot#
迁移到SpringBoot 05 - 事务管理
迁移到SpringBoot 03 - Servlet和Filter
  • 文章目录
  • 站点概览
Orchidflower

Orchidflower

Do one thing at a time, and do well.

77 日志
6 分类
84 标签
GitHub 知乎 OSC 豆瓣
  • 1. Redis自动注册
  • 2. 自定义Bean
  • 3. 关闭自动注册
  • 4. Intellij报错的问题
  • 附录、参考资料
© 2009 - 2024 执子之手
Powered by - Hugo v0.113.0
Theme by - NexT
ICP - 鲁ICP备17006463号-1
0%