赞
踩
前言:网络上找到的文章基本上都是不动脑子互相乱抄的,大部分是用到spring注解+自定义配置类(Java代码)完成,这种做法一点都不springboot,但实际上并不需要编写任何Java代码就能集成,因为springboot本身就已经提供了这样的自动配置,只是默认启动的是另外一个而已,只需要少量的配置就能完成集成。
首先从构建开始,使用idea的构建工具可以直接导入父依赖
<parent>
<groupId>org.springframework.boot</groupId>
<!-- 最后是parent -->
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
父依赖主要定义了springboot的版本,可以有利于统一starter版本,如果自定义依赖版本可以忽略此处
下面真正的开始,只需要在导入依赖时,去除lettuce的依赖即可,引入jedis即可
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
application.properties
其它的配置可以上网查找,也可以参考RedisProperties.class,至于为什么后面有源码介绍
spring.redis.host=192.168.235.128
至此就完成了,下面为测试代码,大家也可以用注解注入的方式来玩
ConfigurableApplicationContext run = SpringApplication.run(HelloWorldApplication.class, args);
RedisTemplate template = (RedisTemplate) run.getBean("redisTemplate");
template.boundValueOps("key");
JedisConnectionFactory jedisConnectionFactory = run.getBean(JedisConnectionFactory.class);
Jedis jedis = ((JedisConnection)jedisConnectionFactory.getConnection()).getJedis();
jedis.set("hello", "hello2");
运行结果
后面是源码的一些分析:
首先我们要知道springboot本身就是基于springioc的一个框架,核心就是springboot提供了非常多的自动配置类,这些配置类都归属于spring-boot-autoconfigure这个jar包下,其命名规则是*AutoConfiguration,例如redis的自动配置类RedisAutoConfiguration
RedisAutoConfiguration.java
@Configuration(proxyBeanMethods = false) @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; } }
这里关键的几个代码是
1.@ConditionalOnClass(RedisOperations.class),意思是存在RedisOperations类则加载此配置类
2.@EnableConfigurationProperties(RedisProperties.class),这个是前面有提到过配置,里面有相关的配置属性
下面为RedisProperties.class的源码,可以看出配置属性的前缀是spring.redis,譬如host在properties文件对应的是spring.redis.host,另外可以看到其中大部分属性是有默认值的,如spring.redis.database=0,因此我并没有做太多其它的配置
@ConfigurationProperties(prefix = "spring.redis") public class RedisProperties { /** * Database index used by the connection factory. */ private int database = 0; /** * Connection URL. Overrides host, port, and password. User is ignored. Example: * redis://user:password@example.com:6379 */ private String url; /** * Redis server host. */ private String host = "localhost";
3.@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
这里导入了两个连接的配置,Lettuce和Jedis,但是为什么会默认使用Lettuce呢,我们可以点开看一下源码
LettuceConnectionConfiguration 的部分源码
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisClient.class)
class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
同样关注**@ConditionalOnClass**这个注解,意思是存在RedisClient类则启用此配置
JedisConnectionConfiguration 部分代码
与LettuceConnectionConfiguration类似,也是判断某些类是否存在
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class, Jedis.class })
class JedisConnectionConfiguration extends RedisConnectionConfiguration {
当前pom.xml的依赖下,LettuceConnectionConfiguration是会飘红的,因为redisClient不存在
如果pom.xml,只是如下面这样引入的话(不做去除引入包和新增引入包),那么上面这个类(LettuceConnectionConfiguration)是不会飘红的,而是JedisConnectionConfiguration 飘红,大家可以对比一下两种依赖方式
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
那么问题来了,为什么我会知道怎么导入呢
大家如果使用idea的话,可以尝试ctrl+左键 点击pom.xml的这行代码
<artifactId>spring-boot-starter-data-redis</artifactId>
点开后找到依赖关系,可以看到默认依赖了lettuce-core这个包,这就是为什么默认情况下springboot集成的是lettuce的方式。
我们继续观察可以看到还有一个依赖spring-data-redis,我们点进去查看一下,可以发现是有定义jedis的依赖的(源码就不贴了)。我们只需要在我们的项目里声明一下,再把lettuce的依赖去掉就可以了。
根据spring-data-redis,按理来说jedis也是会默认依赖进来(没有排除掉),至于为什么实际没有,希望有大神解释一下。
spring-boot-starter-data-redis的pom.xml
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.2.5.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.2.5.RELEASE</version> <scope>compile</scope> <exclusions> <exclusion> <artifactId>jcl-over-slf4j</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>5.2.2.RELEASE</version> <scope>compile</scope> </dependency> </dependencies>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。