spring-boot 整合redis作为数据缓存

本文介绍如何在Spring Boot项目中配置Redis缓存,并实现自定义Key生成器。通过配置文件设置Redis连接参数,如主机名、端口等。此外,还介绍了Spring Boot自动配置Redis的相关原理。

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

添加依赖

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

Redis配置

package com.wisely.ij.config;  
  
import com.fasterxml.jackson.annotation.JsonAutoDetect;  
import com.fasterxml.jackson.annotation.PropertyAccessor;  
import com.fasterxml.jackson.databind.ObjectMapper;  
import org.springframework.cache.CacheManager;  
import org.springframework.cache.annotation.CachingConfigurerSupport;  
import org.springframework.cache.annotation.EnableCaching;  
import org.springframework.cache.interceptor.KeyGenerator;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.data.redis.cache.RedisCacheManager;  
import org.springframework.data.redis.connection.RedisConnectionFactory;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.data.redis.core.StringRedisTemplate;  
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;  
  
import java.lang.reflect.Method;  
  
  
@Configuration  
@EnableCaching  
public class RedisConfig extends CachingConfigurerSupport{  
  
    @Bean  
    public KeyGenerator wiselyKeyGenerator(){  
        return new KeyGenerator() {  
            @Override  
            public Object generate(Object target, Method method, Object... params) {  
                StringBuilder sb = new StringBuilder();  
                sb.append(target.getClass().getName());  
                sb.append(method.getName());  
                for (Object obj : params) {  
                    sb.append(obj.toString());  
                }  
                return sb.toString();  
            }  
        };  
  
    }  
  
    @Bean  
    public CacheManager cacheManager(  
            @SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {  
        return new RedisCacheManager(redisTemplate);  
    }  
  
    @Bean  
    public RedisTemplate<String, String> redisTemplate(  
            RedisConnectionFactory factory) {  
        StringRedisTemplate template = new StringRedisTemplate(factory);  
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);  
        ObjectMapper om = new ObjectMapper();  
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);  
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);  
        jackson2JsonRedisSerializer.setObjectMapper(om);  
        template.setValueSerializer(jackson2JsonRedisSerializer);  
        template.afterPropertiesSet();  
        return template;  
    }  
}  
# REDIS (RedisProperties)  
spring.redis.database= # database name  
spring.redis.host=localhost # server host  
spring.redis.password= # server password  
spring.redis.port=6379 # connection port  
spring.redis.pool.max-idle=8 # pool settings ...  
spring.redis.pool.min-idle=0  
spring.redis.pool.max-active=8  
spring.redis.pool.max-wait=-1  
spring.redis.sentinel.master= # name of Redis server  
spring.redis.sentinel.nodes= # comma-separated list of host:port pairs 

 

@Conditional(MyCondition.class)

 

这句代码可以标注在类上面,表示该类下面的所有@Bean都会启用配置

也可以标注在方法上面,只是对该方法启用配置

 

除了自己自定义Condition之外,Spring还提供了很多Condition给我们用

@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用)

org.springframework.boot:spring-boot-autoconfigure:1.3.0.M2

复制代码
package org.springframework.boot.autoconfigure.redis;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.redis.RedisProperties;
import org.springframework.boot.autoconfigure.redis.RedisProperties.Pool;
import org.springframework.boot.autoconfigure.redis.RedisProperties.Sentinel;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
@ConditionalOnClass({JedisConnection.class, RedisOperations.class, Jedis.class})
@EnableConfigurationProperties
public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }

    @Bean(
        name = {"org.springframework.autoconfigure.redis.RedisProperties"}
    )
    @ConditionalOnMissingBean
    public RedisProperties redisProperties() {
        return new RedisProperties();
    }

    @Configuration
    protected static class RedisConfiguration {
        protected RedisConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean(
            name = {"redisTemplate"}
        )
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
            RedisTemplate template = new RedisTemplate();
            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;
        }
    }

    @Configuration
    @ConditionalOnClass({GenericObjectPool.class})
    protected static class RedisPooledConnectionConfiguration extends RedisAutoConfiguration.AbstractRedisConfiguration {
        protected RedisPooledConnectionConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean
        public RedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
            return this.applyProperties(this.createJedisConnectionFactory());
        }

        private JedisConnectionFactory createJedisConnectionFactory() {
            return this.properties.getPool() != null?
new JedisConnectionFactory(this.getSentinelConfig(), this.jedisPoolConfig()):
new JedisConnectionFactory(this.getSentinelConfig());
        }

        private JedisPoolConfig jedisPoolConfig() {
            JedisPoolConfig config = new JedisPoolConfig();
            Pool props = this.properties.getPool();
            config.setMaxTotal(props.getMaxActive());
            config.setMaxIdle(props.getMaxIdle());
            config.setMinIdle(props.getMinIdle());
            config.setMaxWaitMillis((long)props.getMaxWait());
            return config;
        }
    }

    @Configuration
    @ConditionalOnMissingClass({"org.apache.commons.pool2.impl.GenericObjectPool"})
    protected static class RedisConnectionConfiguration extends RedisAutoConfiguration.AbstractRedisConfiguration {
        protected RedisConnectionConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean
        public RedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
            return this.applyProperties(new JedisConnectionFactory(this.getSentinelConfig()));
        }
    }

    protected abstract static class AbstractRedisConfiguration {
        @Autowired
        protected RedisProperties properties;
        @Autowired(
            required = false
        )
        private RedisSentinelConfiguration sentinelConfiguration;

        protected AbstractRedisConfiguration() {
        }

        protected final JedisConnectionFactory applyProperties(JedisConnectionFactory factory) {
            factory.setHostName(this.properties.getHost());
            factory.setPort(this.properties.getPort());
            if(this.properties.getPassword() != null) {
                factory.setPassword(this.properties.getPassword());
            }

            factory.setDatabase(this.properties.getDatabase());
            if(this.properties.getTimeout() > 0) {
                factory.setTimeout(this.properties.getTimeout());
            }

            return factory;
        }

        protected final RedisSentinelConfiguration getSentinelConfig() {
            if(this.sentinelConfiguration != null) {
                return this.sentinelConfiguration;
            } else {
                Sentinel sentinelProperties = this.properties.getSentinel();
                if(sentinelProperties != null) {
                    RedisSentinelConfiguration config = new RedisSentinelConfiguration();
                    config.master(sentinelProperties.getMaster());
                    config.setSentinels(this.createSentinels(sentinelProperties));
                    return config;
                } else {
                    return null;
                }
            }
        }

        private List<RedisNode> createSentinels(Sentinel sentinel) {
            ArrayList sentinels = new ArrayList();
            String nodes = sentinel.getNodes();
            String[] var4 = StringUtils.commaDelimitedListToStringArray(nodes);
            int var5 = var4.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String node = var4[var6];

                try {
                    String[] ex = StringUtils.split(node, ":");
                    Assert.state(ex.length == 2, "Must be defined as \'host:port\'");
                    sentinels.add(new RedisNode(ex[0], Integer.valueOf(ex[1]).intValue()));
                } catch (RuntimeException var9) {
                    throw new IllegalStateException("Invalid redis sentinel property \'" + node + "\'", var9);
                }
            }

            return sentinels;
        }
    }
}
复制代码

 

复制代码
package org.springframework.boot.autoconfigure.redis;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(
    prefix = "spring.redis"
)
public class RedisProperties {
    private int database = 0;
    private String host = "localhost";
    private String password;
    private int port = 6379;
    private int timeout;
    private RedisProperties.Pool pool;
    private RedisProperties.Sentinel sentinel;

    public RedisProperties() {
    }

    public int getDatabase() {
        return this.database;
    }

    public void setDatabase(int database) {
        this.database = database;
    }

    public String getHost() {
        return this.host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getPort() {
        return this.port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public int getTimeout() {
        return this.timeout;
    }

    public RedisProperties.Sentinel getSentinel() {
        return this.sentinel;
    }

    public void setSentinel(RedisProperties.Sentinel sentinel) {
        this.sentinel = sentinel;
    }

    public RedisProperties.Pool getPool() {
        return this.pool;
    }

    public void setPool(RedisProperties.Pool pool) {
        this.pool = pool;
    }

    public static class Sentinel {
        private String master;
        private String nodes;

        public Sentinel() {
        }

        public String getMaster() {
            return this.master;
        }

        public void setMaster(String master) {
            this.master = master;
        }

        public String getNodes() {
            return this.nodes;
        }

        public void setNodes(String nodes) {
            this.nodes = nodes;
        }
    }

    public static class Pool {
        private int maxIdle = 8;
        private int minIdle = 0;
        private int maxActive = 8;
        private int maxWait = -1;

        public Pool() {
        }

        public int getMaxIdle() {
            return this.maxIdle;
        }

        public void setMaxIdle(int maxIdle) {
            this.maxIdle = maxIdle;
        }

        public int getMinIdle() {
            return this.minIdle;
        }

        public void setMinIdle(int minIdle) {
            this.minIdle = minIdle;
        }

        public int getMaxActive() {
            return this.maxActive;
        }

        public void setMaxActive(int maxActive) {
            this.maxActive = maxActive;
        }

        public int getMaxWait() {
            return this.maxWait;
        }

        public void setMaxWait(int maxWait) {
            this.maxWait = maxWait;
        }
    }
}
复制代码

 

http://www.cnblogs.com/laoniu85/p/5224079.html

转载:http://www.cnblogs.com/softidea/p/5751595.html

转载于:https://www.cnblogs.com/diyunpeng/p/6366479.html

### Spring Boot 中 `spring-boot-data-redis` 和 `spring-boot-starter-data-redis` 的区别 #### 定义与用途 `sprng-boot-starter-data-redis` 是一个启动器(Starter),它包含了构建基于 Redis 数据存储的应用程序所需的所有依赖项。这个 Starter 自动引入了核心库,例如 `spring-data-redis` 和底层的 Redis 驱动程序(如 Jedis 或 Lettuce)。通过这种方式简化了项目的配置过程[^1]。 另一方面,`spring-boot-data-redis` 并不是一个独立的模块名称,而是通常指代由 `spring-boot-starter-data-redis` 提供的核心功能之一——即对 Redis 数据访问的支持能力。换句话说,它是 `spring-boot-starter-data-redis` 所封装的功能的一部分[^2]。 #### 主要差异总结 以下是两者的主要区别: 1. **命名含义** - `spring-boot-starter-data-redis`: 这是一个完整的 Starter 模块,用于快速集成 Redis 功能到 Spring Boot 应用中。 - `spring-boot-data-redis`: 更像是描述性的术语,表示 Spring Boot数据Redis 支持的整体概念,而不是具体的 Maven/Gradle 依赖项[^3]。 2. **依赖关系** - 当你在项目中添加 `spring-boot-starter-data-redis` 时,会自动拉取多个必要的子依赖项,其中包括但不限于: - `spring-data-redis`: 实现 Redis 数据操作的核心抽象接口。 - `lettuce-core` 或 `jedis`: Redis Java 客户端驱动程序的选择,默认情况下可能会优先选用其中之一作为默认实现。 3. **自动化配置** - 使用 `spring-boot-starter-data-redis` 后,Spring Boot 将提供一系列开箱即用的自动化配置选项来管理 Redis 连接池以及序列化策略等高级特性。这些都无需开发者额外编写繁琐的手动代码即可完成初始化工作[^2]。 4. **实际应用中的体现** 下面展示了一个简单的测试案例片段,其中展示了如何利用 `RedisTemplate` 来保存键值对并设置过期时间: ```java @SpringBootTest class CodeApplicationTests { @Autowired private RedisTemplate<String, Object> redisTemplate; @Test public void testRedisOperations(){ // 设置 key-value 到缓存里,并指定存活时间为60秒 redisTemplate.opsForValue().set("testKey","value"); redisTemplate.expire("testKey",60L, TimeUnit.SECONDS); String result = (String) redisTemplate.opsForValue().get("testKey"); Assertions.assertEquals(result,"value"); } } ``` 此代码段表明,在成功注入 `RedisTemplate` 后可以非常方便地执行各种针对 Redis 缓存的操作命令[^3]。 #### 结论 综上所述,“`spring-boot-data-redis`”更多是指向于一种逻辑上的表述形式,而 “`spring-boot-starter-data-redis`”才是具体可被加入工程文件里的组件包名。如果希望在自己的应用程序里面轻松接入 Redis,则应该直接引用后者。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值