Redis系列一 - springboot 集成 redis Demo和原理

小助手 1年前 ⋅ 996 阅读

作者:hry2015

原文地址 https://blog.csdn.net/hry2015/article/details/74276423

代码仓库:https://github.com/hryou0922/spring_boot/tree/master/redis/src/main/java/com/hry/spring/redis/simple

1.概述

本文介绍如何通过 springboot 集成 redis 并简单介绍其原理。

2.Demo 和原理

2.1. application.properties

application.properties 配置参数如下

spring.redis.database=0
spring.redis.host=192.168.188.7
spring.redis.password=
spring.redis.port=6379
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0  
spring.redis.pool.max-active=8  
spring.redis.pool.max-wait=-1

备注: 如果你要使用集群 redis,则可以配置以下参数 spring.redis.sentinel.* 或 spring.redis.cluster.*

2.2. RedisProperties

以上参数会被自动封装到 RedisProperties 中: 此类被 @ConfigurationProperties 注解,表示从外部文件(如 application.properties)注入属性值

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
    /**
     * Database index used by the connection factory.
     */
    private int database = 0;

    /**
     * Redis url, which will overrule host, port and password if set.
     */
    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;
    // 其它参数略
}

2.3. RedisAutoConfiguration

因为此类被 @EnableConfigurationProperties 注解,所以 spring boot 会触发对 RedisProperties 执行自动绑定属性值。

此类会自动创建 bean 对象: redis 连接池 JedisConnectionFactory 和 redis 模板类 (RedisTemplate 和 StringRedisTemplate)。我们会直接在应用中通过 @Autowire 注入以上对象

/**
 * EnableAutoConfiguration Auto-configuration for Spring Data's Redis support.
 *
 */
@Configuration
// 如果有以下三个类,则可以初始化此类
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
// @EnableConfigurationProperties:对RedisProperties执行自动绑定属性值
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {

    @Configuration
    //  如果有以下一个类,则可以初始化此类
    @ConditionalOnClass(GenericObjectPool.class)
    protected static class RedisConnectionConfiguration {

        // 初始化JedisConnectionFactory工厂类对象,参数来自RedisProperties
        // 配置参数有:线程池,sentinel,cluster
        @Bean
        @ConditionalOnMissingBean(RedisConnectionFactory.class)
        public JedisConnectionFactory redisConnectionFactory()
            throws UnknownHostException {
            return applyProperties(createJedisConnectionFactory());
        }


    // 配置类 
    @Configuration
    protected static class RedisConfiguration {
        // 初始化bean
        @Bean
        @ConditionalOnMissingBean(name = "redisTemplate")
        public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory)
                throws UnknownHostException {
            RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }

        // 初始化bean
@Bean       @ConditionalOnMissingBean(StringRedisTemplate.class)
        public StringRedisTemplate stringRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)
                throws UnknownHostException {
            StringRedisTemplate template = new StringRedisTemplate();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }

    }


2.4. FirstExample

演示 RedisTemplate 的用法:

@Service
public class FirstExample {
    @Autowired
    private RedisTemplate<String, String> template;

    public void save(String userId, String value) {
        template.boundListOps(userId).leftPush(value);
    }
}

2.5. FirstApplication

springboot 启动类

@SpringBootApplication
public class FirstApplication {
    private static final Logger log = LoggerFactory.getLogger(FirstApplication.class);

    public static void main(String[] args) {
        log.info("Start FirstApplication.. ");
        SpringApplication.run(FirstApplication.class, args);
    }
}

查看源码 @SpringBootApplication 被 @EnableAutoConfiguration 注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
....
}

被 @EnableAutoConfiguration 注解时,springboot 启动时会扫描对应 jar 包中的 META-INF/spring-autoconfigure-metadata.properties 文件,并初始化里面的配置的类。查看 spring-autoconfigure-metadata.properties,里面配置了上文的 RedisAutoConfiguration 类,所以我们可以直接在类中注入 RedisTemplate.

...
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration=
... 

2.6. FirstApplicationTests

测试类,执行类会在 redis 中创建一个值

@RunWith(SpringRunner.class)
@SpringBootTest(classes=FirstApplication.class)
public class FirstApplicationTests {
    @Autowired
    private FirstExample firstExample;

    @Test
    public void save(){
        firstExample.save("name", "value");
    }
}

3.代码 ##

上文的代码详细见这里


全部评论: 0

    我有话说: