Spring Boot:通过spring-boot-starter-data-redis源码了解starter和autoconfigure模块

注:本文Spring Boot为2.X版本
在Spring Boot中,官方提供了spring-boot-autoconfigure包和starter包用来帮助我们简化配置,比如之前要建一个Spring mvc项目,需要我们配置web.xml,dispatcherservlet-servlet.xml,applicationContext.xml等等。而在Spring Boot中只需要在pom中引入

   <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
   </dependency>

就能完成之前所有的工作了。简直so easy啊。
但是只会用是不行的,还要知其所以然,本文以官方的starter:spring-boot-starter-data-redis为例,从源码层面上分析整个自动化配置的过程。以期对starter和autoconfigure这两个Spring Boot的核心模块进行梳理。
了解原理后,我会通过模拟spring-boot-starter-data-redis,并使用Jedis来创建一个处理redis的自定义starter:my-redis-starter。源码下载 点我,最后会详细说明自定义starter的创建过程。

在Spring Boot中使用默认的redis客户端只需要
在pom.xml中引入

 <dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

然后在application.properties中配置ip,密码等必要参数

spring.redis.host=106.15.108.50
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
#等等

就可以直接在我们的业务中调用org.springframework.data.redis.core.RedisTemplate来处理缓存的相关操作了。

一.RedisTemplate的注入

让我们先来看下RedisTemplate是如何被注入的。

1.RedisProperties

application.properties中ctrl+左击redis的相关配置项,会打开spring-boot-autoconfigure\2.0.2.RELEASE\spring-boot-autoconfigure-2.0.2.RELEASE.jar中的RedisProperties
在这里插入图片描述
打开org.springframework.boot.autoconfigure.data.redis.RedisProperties.class

@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";

	/**
	 * Login password of the redis server.
	 */
	private String password;

	/**
	 * Redis server port.
	 */
	private int port = 6379;

	/**
	 * Whether to enable SSL support.
	 */
	private boolean ssl;

	/**
	 * Connection timeout.
	 */
	private Duration timeout;

	private Sentinel sentinel;

	private Cluster cluster;

	private final Jedis jedis = new Jedis();

	private final Lettuce lettuce = new Lettuce();
	......
}

(1) @ConfigurationProperties(prefix = "spring.redis") 设置绑定属性的前缀,然后看下前面的一些属性,是不是很眼熟?前缀+属性名就是之前在application.properties中配置的,如果我们没有配置端口这种属性,那么这里也会提供部分默认配置。
当然,只是这些是没办法让Spring Boot在启动时扫描到该类的,所以需要下一个类org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration.class
然后我们还能找到

private final Jedis jedis = new Jedis();
private final Lettuce lettuce = new Lettuce();

一般用Java操作redis用的较多几个Java客户端为Jedis,Redisson,Lettuce。这里可知官方提供的spring-boot-starter-data-redis底层是用Jedis/Lettuce实现的,知道了这个我们也能够借鉴这个starter来使用其他的客户端来实现了。

2.RedisAutoConfiguration

打开org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration.class

@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;
	}
}

(1)@Configuration常见的配置注解,内部含有一个以上的@Bean,让Spring能扫描到内部的@Bean,当然在Spring Boot中,默认只会扫描到启动类所在包或其下级包的类,所以还会通过其他的设置来让这个类被扫描到,这个后面会详细说明。

@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

(2)@ConditionalOnClass(RedisOperations.class),当存在RedisOperations类时才会进行扫描,这个类什么时候被引入classpath的之后会提到。
(3)@EnableConfigurationProperties(RedisProperties.class)RedisProperties 类被扫描到的关键。这时,如果RedisAutoConfiguration被扫描到,则同时也会去扫描RedisProperties类。
(4)@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })通过@Import注解方式生成类实例并注入Spring容器。

@Import注解通过导入的方式实现把实例加入springIOC容器中

让我们打开JedisConnectionConfiguration简要看下

@Configuration
@ConditionalOnClass({
   
    GenericObjectPool.class, JedisConnection.class, Jedis.class })
class JedisConnectionConfiguration extends RedisConnectionConfiguration {
   
   
	private final RedisProperties properties;
	private final List<JedisClientConfigurationBuilderCustomizer> builderCustomizers;
	JedisConnectionConfiguration(RedisProperties properties,
			ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
			ObjectProvider<RedisClusterConfiguration> clusterConfiguration,
			ObjectProvider<List
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

团子ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值