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

本文详细介绍了SpringBoot中集成Redis的全过程,包括配置文件的解析、自动配置类的作用及RedisCacheManager的初始化流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考网页

SpringBoot集成Redis的原理

https://blog.youkuaiyun.com/hry2015/article/details/74276423

https://blog.youkuaiyun.com/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进行二次配置。

转载于:https://my.oschina.net/u/3866531/blog/1858069

### 如何在SpringBoot配置Redis连接池 #### 1. 基本配置 在 `application.properties` 或 `application.yml` 文件中,可以设置 Redis 的基本连接信息。以下是具体的配置示例: 对于 `application.properties`: ```properties spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= spring.redis.database=0 ``` 对于 `application.yml`: ```yaml spring: redis: host: 127.0.0.1 port: 6379 password: database: 0 ``` 这些参数分别表示 Redis 主机地址、端口号、密码以及数据库索引[^1]。 --- #### 2. 高级配置Redis 连接池 为了提高性能并优化资源管理,通常需要配置 Redis 连接池。可以通过 JedisPoolConfig 对象实现更精细的控制。以下是一个完整的 Java 配置类示例: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; @Configuration public class RedisConfig { @Bean public JedisPool jedisPool() { // 创建 JedisPoolConfig 实例 JedisPoolConfig poolConfig = new JedisPoolConfig(); // 设置最大空闲连接数 poolConfig.setMaxIdle(10); // 设置最小空闲连接数 poolConfig.setMinIdle(5); // 设置最大总连接数 poolConfig.setMaxTotal(20); // 设置获取连接的最大等待时间(毫秒) poolConfig.setMaxWaitMillis(5000); // 初始化 JedisPool 并返回实例 return new JedisPool(poolConfig, "127.0.0.1", 6379); } } ``` 此代码片段展示了如何通过 `JedisPoolConfig` 自定义连接池的行为,例如最大连接数、最小空闲连接数等[^2]。 --- #### 3. 使用 RedisTemplate 执行操作 Spring 提供了强大的工具类 `RedisTemplate` 来简化与 Redis 的交互过程。下面展示了一个简单的例子,说明如何存储和检索数据: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @Service public class RedisService { @Autowired private RedisTemplate<String, String> redisTemplate; public void setValue(String key, String value) { redisTemplate.opsForValue().set(key, value); } public String getValue(String key) { return redisTemplate.opsForValue().get(key); } } ``` 如果需要确保多个操作在一个事务中完成,则可以使用 `SessionCallback` 接口来执行批量操作[^5]。 --- #### 4. 完整流程总结 - **第一步**:在项目的配置文件中指定 Redis 的基础连接信息。 - **第二步**:创建自定义的连接池配置类以增强性能。 - **第三步**:编写服务层逻辑,利用 `RedisTemplate` 或其他高级 API 操作 Redis 数据。 通过上述方法,可以在 Spring Boot 应用程序中高效地管理和使用 Redis 资源[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值