redisUtil 类

本文介绍了一个基于Spring Boot的Redis缓存工具类,该工具类提供了缓存基本对象、List、Set及Map数据的方法,并支持设置缓存过期时间。

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;


/** 
 * @ClassName: RedisCacheUtil 
 * @Description: redis缓存工具类
 * @author li
 * @date 2018年3月20日 上午11:04:13 
 * @param <T> 
 */ 
 
@Service
@SuppressWarnings({ "rawtypes", "unchecked", "hiding"})
public class RedisCacheUtil<T> {

	@Autowired
    public RedisTemplate redisTemplate;
    
    /** 
     * @Title: setCacheObject 
     * @param key
     * @param value
     * @return
     * @Description: 缓存基本的对象,Integer、String、实体类等 
     */ 
    public <T> void setCacheObject(String key, T value) {
        redisTemplate.opsForValue().set(key, value);
    }
    /** 
     * @Title: setCacheObject 
     * @param key
     * @param value
     * @param timeOut 超时时间
     * @param timeUnit 超时单位 
     * @return
     * @Description: 缓存基本的对象,Integer、String、实体类等
     */ 
    public <T> void setCacheObject(String key, T value,Long timeOut,TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeOut, timeUnit);
    }
   
    /** 
     * @Title: getCacheObject 
     * @param key
     * @return
     * @Description: 获取缓存基本对象
     */ 
    public <T> T getCacheObject(String key) {
        return (T) redisTemplate.opsForValue().get(key);
    }

    /**
     * 缓存List数据
     * @param key      缓存的键值
     * @param dataList 待缓存的List数据
     * @return 缓存的对象
     */
	public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList) {
        ListOperations listOperation = redisTemplate.opsForList();
        if (null != dataList) {
            int size = dataList.size();
            for (int i = 0; i < size; i++) {
                listOperation.leftPush(key, dataList.get(i));
            }
        }
        return listOperation;
    }

    /**
     * 获得缓存的list对象
     * @param key 缓存的键值
     * @return 缓存键值对应的数据
     */
    public <T> List<T> getCacheList(String key) {
        List<T> dataList = new ArrayList<T>();
        ListOperations<String, T> listOperation = redisTemplate.opsForList();
        Long size = listOperation.size(key);

        for (int i = 0; i < size; i++) {
            dataList.add(listOperation.index(key,i));
        }
        return dataList;
    }

    /**
     * 缓存Set
     * @param key     缓存键值
     * @param dataSet 缓存的数据
     * @return 缓存数据的对象
     */
    public <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet) {
        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
        Iterator<T> it = dataSet.iterator();
        while (it.hasNext()) {
            setOperation.add(it.next());
        }
        return setOperation;
    }

    /**
     * 获得缓存的set
     * @param key
     * @return
     */
    public Set<T> getCacheSet(String key) {
        Set<T> dataSet = new HashSet<T>();
        BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key);
        Long size = operation.size();
        for (int i = 0; i < size; i++) {
            dataSet.add(operation.pop());
        }
        return dataSet;
    }

    /**
     * 缓存Map
     * @param key
     * @param dataMap
     * @return
     */
    public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap) {

        HashOperations hashOperations = redisTemplate.opsForHash();
        if (null != dataMap) {
            for (Map.Entry<String, T> entry : dataMap.entrySet()) {
                hashOperations.put(key, entry.getKey(), entry.getValue());
            }
        }
        return hashOperations;
    }

    /**
     * 获得缓存的Map
     *
     * @param key
     * @return
     */
    public <T> Map<String, T> getCacheMap(String key) {
        Map<String, T> map = redisTemplate.opsForHash().entries(key);
        return map;
    }


    /**
     * 缓存Map
     *
     * @param key
     * @param dataMap
     * @return
     */
    public <T> HashOperations<String, Integer, T> setCacheIntegerMap(String key, Map<Integer, T> dataMap) {
        HashOperations hashOperations = redisTemplate.opsForHash();
        if (null != dataMap) {
            for (Map.Entry<Integer, T> entry : dataMap.entrySet()) {
                hashOperations.put(key, entry.getKey(), entry.getValue());
            }
        }
        return hashOperations;
    }

    /**
     * 获得缓存的Map
     *
     * @param key
     * @return
     */
    public <T> Map<Integer, T> getCacheIntegerMap(String key) {
        Map<Integer, T> map = redisTemplate.opsForHash().entries(key);
        return map;
    }
}

 

<think>好的,我现在需要解决用户的问题:在Spring Boot项目中,RedisUtil使用@Resource注解注入StringRedisTemplate时出现为null的情况。用户之前已经询问过如何通过Java删除Redis中的层级数据,现在遇到了依赖注入的问题。我需要仔细分析可能的原因,并提供解决方案。 首先,用户提到使用@Resource注解,但StringRedisTemplate没有被正确注入,导致null。常见的原因可能有几个方面: 1. **组件扫描问题**:RedisUtil可能没有被Spring容器管理,即没有加上@Component或其他注解,导致Spring无法创建实例,自然无法注入依赖。 2. **注解使用错误**:@Resource默认按名称注入,如果名称不匹配,可能需要指定name属性。或者应该使用@Autowired按型注入。 3. **配置问题**:StringRedisTemplate是否在Spring上下文中正确配置?用户可能没有正确配置Redis相关的依赖或配置,导致Bean不存在。 4. **静态方法或字段**:如果RedisUtil中的StringRedisTemplate是静态变量,@Resource无法注入到静态字段,需要特殊处理。 5. **包扫描路径**:如果RedisUtil所在的包不在Spring Boot的主应用扫描范围内,组件无法被识别,导致依赖注入失败。 接下来,我需要逐一排查这些可能性。用户提供的代码示例中,RedisUtil可能没有正确注解,或者StringRedisTemplate的Bean未正确配置。另外,静态变量的问题也需要注意。例如,用户可能在工具中使用了静态的StringRedisTemplate,但直接使用@Resource注入静态变量是不行的,需要通过setter方法或@PostConstruct来初始化。 另外,检查是否缺少必要的依赖,比如spring-boot-starter-data-redis,或者配置文件中Redis连接信息错误,导致StringRedisTemplate无法初始化,进而注入失败。 还需要考虑是否有多个StringRedisTemplate的Bean导致冲突,这时候@Resource可能需要指定名称。或者用户自定义了RedisTemplate的配置,但没有指定名称,导致注入时名称不匹配。 总结可能的解决方案步骤: 1. 确保RedisUtil被Spring管理,添加@Component或@Service注解。 2. 检查StringRedisTemplate的注入方式,使用@Autowired按型注入,或@Resource按名称注入,并确认名称是否正确。 3. 检查包扫描路径,确保RedisUtil在Spring Boot主应用的子包下。 4. 避免在静态变量上直接注入,改用实例变量,或者通过setter方法注入。 5. 检查Redis配置是否正确,确保StringRedisTemplate的Bean被正确创建。 6. 检查依赖是否添加,pom.xml或build.gradle中是否有spring-boot-starter-data-redis。 另外,可能用户在使用工具时,直接通过new RedisUtil()来实例化,而不是由Spring注入,这会导致依赖无法注入。应该通过@Autowired获取RedisUtil实例,而不是手动创建。 最后,给出具体的代码示例,展示如何正确注解、注入依赖,以及可能的配置调整。同时提醒用户检查配置文件和依赖,确保Redis连接正常。</think>在Spring Boot项目中解决`StringRedisTemplate`注入为null的问题,需要从**组件管理、依赖注入方式、配置完整性**三方面入手。以下是分步解决方案: --- ### 一、核心问题诊断 #### 1. 组件未被Spring管理(最常见原因) - **错误现象**:工具未标注`@Component`等注解,导致Spring无法创建实例 - **验证方法**:检查声明是否包含以下任意注解 ```java @Component // 通用组件 @Service // 服务层组件 @Repository // 数据层组件 ``` #### 2. 注入方式选择错误 - `@Resource`默认按**名称匹配**(name属性) - `@Autowired`默认按**型匹配** - **错误示例**: ```java public class RedisUtil { @Resource // 未指定name时要求变量名与bean名称一致 private StringRedisTemplate redisTemplate; // 变量名必须与bean名称完全相同 } ``` #### 3. 配置缺失(关键配置检查) - 检查`pom.xml`是否包含必要依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` - 检查`application.yml`配置: ```yaml spring: redis: host: 127.0.0.1 port: 6379 password: yourpassword database: 0 ``` --- ### 二、标准解决方案 #### 方案1:正确组件声明+型注入(推荐) ```java @Component // 必须添加组件注解 public class RedisUtil { @Autowired // 按型注入StringRedisTemplate private StringRedisTemplate stringRedisTemplate; public void setKey(String key, String value) { stringRedisTemplate.opsForValue().set(key, value); } } ``` #### 方案2:名称匹配注入(需确认Bean名称) ```java @Component public class RedisUtil { @Resource(name = "stringRedisTemplate") // 显式指定bean名称 private StringRedisTemplate template; } ``` --- ### 三、特殊场景处理 #### 场景1:静态工具注入 ```java @Component public class RedisUtil { private static StringRedisTemplate staticTemplate; @Autowired public void setStringRedisTemplate(StringRedisTemplate template) { RedisUtil.staticTemplate = template; // 通过setter注入静态变量 } } ``` #### 场景2:自定义配置 ```java @Configuration public class RedisConfig { @Bean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(factory); template.setKeySerializer(RedisSerializer.string()); return template; } } ``` --- ### 四、验证流程 1. **检查Bean注册情况** ```java @SpringBootTest class RedisUtilTest { @Autowired private ApplicationContext context; @Test void checkBeanExistence() { assertNotNull(context.getBean(StringRedisTemplate.class)); assertNotNull(context.getBean(RedisUtil.class)); } } ``` 2. **注入有效性测试** ```java @SpringBootTest class RedisUtilTest { @Autowired private RedisUtil redisUtil; @Test void testSetKey() { redisUtil.setKey("testKey", "Hello World"); assertEquals("Hello World", redisUtil.getStringRedisTemplate().opsForValue().get("testKey")); } } ``` --- ### 五、常见错误排查表 | 错误现象 | 检查点 | 解决方案 | |--------------------------|-------------------------------|----------------------------------| | 注入字段始终为null | 1. 是否添加@Component注解<br>2. 是否通过new创建实例 | 1. 添加组件注解<br>2. 使用@Autowired获取实例 | | NoSuchBeanDefinition异常 | 1. Redis依赖是否引入<br>2. 配置参数是否正确 | 1. 检查pom.xml依赖<br>2. 验证application.yml配置 | | 连接超时 | 1. Redis服务是否运行<br>2. 防火墙设置 | 1. 启动Redis服务<br>2. 开放6379端口 | --- ### 六、性能优化建议 1. **延迟初始化配置** ```yaml spring: redis: timeout: 3000 lettuce: pool: max-active: 8 max-idle: 8 ``` 2. **连接池监控** ```java @Autowired private RedisConnectionFactory factory; public void printPoolStats() { if (factory instanceof LettuceConnectionFactory) { LettuceConnectionFactory lcf = (LettuceConnectionFactory) factory; System.out.println("Active connections: " + lcf.getRequiredClientConfiguration().getPool().getMetrics().map(PoolMetrics::getAcquired)); } } ``` ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值