文档章节

SpringBoot下Redis相关配置是如何被初始化的

k
 karma123
发布于 07/17 14:00
字数 1635
阅读 99
收藏 2

参考网页

SpringBoot集成Redis的原理

https://blog.csdn.net/hry2015/article/details/74276423

https://blog.csdn.net/hry2015/article/details/75451705

application.yml配置文件中的属性是如何读入到程序中的?

RedisProperties类(org.springframework.boot.autoconfigure.data.redis.RedisProperties

application.properties配置参数示例

spring.redis.database=0

spring.redis.host=192.168.188.7

spring.redis.password=123

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

application.yml配置参数示例

    spring:

      cache:

        #缓存名称

        #cache-names: guavaDemo

        #缓存最大数量500条, 缓存失效时间 6个小时

        #guava.spec: maximumSize=500,expireAfterWrite=360m

      # REDIS (RedisProperties)  

      redis :

        host : localhost # server host  

        port : 6379 # connection port  

        password : 123

        database : 1

        pool.max-idle : 8 # pool settings ...  

        pool.min-idle : 1

        pool.max-active : 8  

        pool.max-wait : -1  

源码

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

    // 其它参数略

}

源码分析

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

调试--在RedisProperties中打个断点,比如设置database属性值的地方

把database 的属性值设置为1(默认为0,就是Redis数据库的第一个索引的库,1表示第二个索引的库)。在RedisProperties的setDatabase方法上打个断点,如下图

启动系统,运行到断点了,如下图

说明系统初始化时,确实运行到了RedisProperties的代码里面,并且根据application.properties文件的配置参数对RedisProperties的属性进行了注入。

RedisAutoConfiguration类

关键部分源码

/**

 * 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;

        }


    }

源码分析

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

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

比如使用RedisTemplate如下

项目启动类启动时如何关联到配置类RedisAutoConfiguration

启动类

查看源码@SpringBootApplication被@EnableAutoConfiguration注解

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

查看我的实际项目中@EnableAutoConfiguration的扫描对象

项目启动时,主启动类被@EnableAutoConfiguration注解,会扫描其引入的jar包中的spring.factories文件。

打开spring.factories文件,可以发现里面有org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration这个类。所以会初始化此类进行相关的配置。

★小结:application.yml配置文件中的属性是如何读入到程序中的?

1)项目主启动类上被@SpringBootApplication注解,@SpringBootApplication又被@EnableAutoConfiguration注解。@EnableAutoConfiguration会触发扫描项目引入的jar包中的spring.factories文件。主启动类再加上注解@EnableCaching后,这样就会触发初始化类org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration。

2)RedisAutoConfiguration被@EnableConfigurationProperties注解,会触发对RedisProperties执行自动绑定属性值。

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

RedisCacheManager是如何被初始化的

总的思路

实际上SpringBoot中所有Bean都有默认的配置和实现,也就是什么都不写就可以直接运行。

但是如果程序员写一个Bean的实现,那么SpringBoot会采用程序员写的。

@EnableCaching和application.yml

缓存管理接口org.springframework.cache.CacheManager,SpringBoot就是通过此类实现缓存的管理。redis对应此接口的实现类是org.springframework.data.redis.cache.RedisCacheManager。下面介绍此类如何生成。

配置application.properties的spring.redis.* 属性后,主启动类加上注解@EnableCaching后,spring会执行RedisAutoConfiguration,初始化RedisTemplate和StringRedisTemplate。

猜测——虽然SpringBoot因为主启动类的@EnableAutoConfiguration注解会扫描引入的jar包的spring.factories文件,但是只有主启动类加上@EnableCaching注解后,诸如RedisAutoConfiguration的缓存类配置对象才会真的被初始化。

★SpringBoot如何对RedisCacheManager做的初始化--RedisCacheConfiguration会将RedisAutoConfiguration生成的RedisTemplate注入方法生成RedisCacheManager

RedisAutoConfiguration关键代码

@Configuration

@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })

@EnableConfigurationProperties(RedisProperties.class)

public class RedisAutoConfiguration {

/**

 * Standard Redis configuration.

 */

@Configuration

protected static class RedisConfiguration {

    ….

    @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

    @ConditionalOnMissingBean(StringRedisTemplate.class)

    public StringRedisTemplate stringRedisTemplate(

        RedisConnectionFactory redisConnectionFactory)

            throws UnknownHostException {

        StringRedisTemplate template = new StringRedisTemplate();

        template.setConnectionFactory(redisConnectionFactory);

        return template;

    }


}


}

RedisCacheConfiguration关键代码

@Configuration

@AutoConfigureAfter(RedisAutoConfiguration.class)

@ConditionalOnBean(RedisTemplate.class)

@ConditionalOnMissingBean(CacheManager.class)

@Conditional(CacheCondition.class)

class RedisCacheConfiguration {


    private final CacheProperties cacheProperties;


    private final CacheManagerCustomizers customizerInvoker;


    RedisCacheConfiguration(CacheProperties cacheProperties,

        CacheManagerCustomizers customizerInvoker) {

        this.cacheProperties = cacheProperties;

        this.customizerInvoker = customizerInvoker;

    }


    @Bean

    public RedisCacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) {

        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);

        cacheManager.setUsePrefix(true);

        List<String> cacheNames = this.cacheProperties.getCacheNames();

        if (!cacheNames.isEmpty()) {

            cacheManager.setCacheNames(cacheNames);

        }

        return this.customizerInvoker.customize(cacheManager);

    }


}

★RedisAutoConfiguration关键代码和RedisCacheConfiguration关键代码的分析

项目主启动类上被@SpringBootApplication注解,@SpringBootApplication又被@EnableAutoConfiguration注解。@EnableAutoConfiguration会触发扫描项目引入的jar包中的spring.factories文件,这样就会初始化类org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration。 RedisAutoConfiguration生成RedisTemplate。RedisCacheConfiguration通过类自身的cacheManager方法注入RedisTemplate并生成RedisCacheManager对象。

以上就是RedisCacheManager对象生成的过程。以下三点:

1)POM文件中引入spring-boot-starter-redis

2)主启动类上加上注解@EnableCaching

3)application.yml中的配置信息

这三点就能保证项目中引入Redis。RedisCacheManager对象由系统自动生成,自己也可以对RedisCacheManager对象做个性化的配置。

如何对RedisCacheManager做个性化的配置

个性化配置RedisCacheManager示例代码

@SpringBootApplication

@EnableCaching // 启动缓存

public class CacheApplication {

    private static final Logger log = LoggerFactory.getLogger(CacheApplication.class);


    public static void main(String[] args) {

        log.info("Start CacheApplication.. ");

        SpringApplication.run(CacheApplication.class, args);


    }


    /**

     * 重新配置RedisCacheManager

     * @param rd

     */

    @Autowired

    public void configRedisCacheManger(RedisCacheManager rd){

        rd.setDefaultExpiration(100L);

    }

}

分析

示例代码只是对key的有效期进行了配置。

也可以直接设计一个@Configuration注解的配置类,在其中使用@Bean注解生成一个RedisCacheManager类。系统也会采用自己写的这个RedisCacheManager。

★总结

Spring(SpringBoot)已经帮我们生成一个RedisCacheManager并进行了配置。我们再可以对这个RedisCacheManager进行二次配置。

© 著作权归作者所有

共有 人打赏支持
k
粉丝 8
博文 77
码字总数 61515
作品 0
丰台
私信 提问
SpringBoot 学习二:操作数据库

本文将从以下几个方面介绍: 前言 配置数据源 SpringBoot 整合 Mybatis SpringBoot 整合 JdbcTemplate SpringBoot 整合 Redis 前言 在上篇文章 SpringBoot 学习一 中已经学习了 SpringBoot的...

tsmyk0715
09/26
0
0
【SpringBoot2.0系列08】SpringBoot之redis数据缓存管理

【SpringBoot2.0系列01】初识SpringBoot 【SpringBoot2.0系列02】SpringBoot之使用Thymeleaf视图模板 【SpringBoot2.0系列03】SpringBoot之使用freemark视图模板 【SpringBoot2.0系列04】Spr...

余空啊
08/20
0
0
springBoot 搭建web项目(前后端分离,附项目源代码地址)

概述 该项目包含springBoot-example-ui 和 springBoot-example,分别为前端与后端,前后端分离,利用ajax交互。 前端html 技术: + + + + 该项目git地址:https://github.com/jiangcaijun/sp...

开源小菜鸟2333
2017/11/01
0
0
恒宇少年/spring-boot-chapter

简书整套文档以及源码解析 专题 专题名称 专题描述 001 Spring Boot 核心技术 讲解SpringBoot一些企业级层面的核心组件 002 Spring Cloud 核心技术 对Spring Cloud核心技术全面讲解 003 Quer...

恒宇少年
04/19
0
0
SpringBoot整合Redis、ApacheSolr和SpringSession

一、简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐。它提供了各种starter简化很多繁琐的配置。SpringBoot整合Druid、Mybatis已经司空见惯,在这里就不详细介绍了。今天...

小忽悠
07/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

最重要的是做什么,而不是怎么做。

最重要的是做什么,而不是怎么做。 做什么是战略,怎么做是战术。将军下令说,天黑前拿下这座山头,这是战略。手下的士兵可以不知道为什么要拿下这座山头,还非得是天黑之前,但士兵必须知道...

我是菜鸟我骄傲
今天
1
0
w, vmstat, top, sar, nload命令查看系统状态信息

w/uptime 查看系统负载 cat /proc/cpuinfo 查看cpu核数 vmstat 监控系统状态,用法 vmstat 1,关键的几列: r, b, swpd, si, so, bi, bo, us, wa top 查看进程使用资源情况 top -c 显示详细的...

野雪球
今天
2
0
小白创建一个spring boot项目

进入 https://start.spring.io/

lilugirl
今天
3
0
Alibaba Java诊断利器Arthas实践--使用redefine排查应用奇怪的日志来源

背景 随着应用越来越复杂,依赖越来越多,日志系统越来越混乱,有时会出现一些奇怪的日志,比如: [] [] [] No credential found 那么怎样排查这些奇怪的日志从哪里打印出来的呢?因为搞不清...

hengyunabc
今天
2
0
home hosts

home hosts lwk@qwfys:~$ cat /etc/hosts127.0.0.1 localhost127.0.1.1 qwfys192.168.56.101vm600.qwfys.com39.108.212.91alpha1.ppy.com39.108.117.122alpha2.p......

qwfys
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部