问题背景
在学习redis时,需要在测试类中创建一个自己的redis工具类。
问题重现
@SpringBootTest
public class redisTest {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Test
void test() {
RedisUtiles redisUtiles1 = new RedisUtiles();
Product product = redisUtiles1.getObject("product", Product.class);
System.out.println(product);
}
}
其中new了一个RedisUtiles对象
运行结果报错如下
java.lang.NullPointerException: Cannot invoke "org.springframework.data.redis.core.RedisTemplate.opsForValue()" because "this.redisTemplate" is null
意思为redisTemplate为空
@SpringBootTest
public class redisTest {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private RedisUtiles redisUtiles;
@Test
void test() {
Product product = redisUtiles.getObject("product", Product.class);
System.out.println(product);
}
}
通过@Autowired创建的redisTemplate则能正常运行
RedisTemplate类
@Component
public class RedisUtiles {
public RedisUtiles() {
System.out.println("空参构造");
}
@Autowired
private RedisTemplate<String, String> redisTemplate;
final Integer defaultTTL = 30;
final TimeUnit defaltTimeUnit = TimeUnit.MINUTES;
public <T> void setObject(String key, T value) {
redisTemplate.opsForValue().set(key, JSON.toJSONString(value), defaultTTL, defaltTimeUnit);
}
public <T> void setObject(String key, T value, final Integer TTL, final TimeUnit timeUnit) {
redisTemplate.opsForValue().set(key, JSON.toJSONString(value), TTL, timeUnit);
}
public <T> T getObject(String key, Class<T> tClass) {
String jsonString = redisTemplate.opsForValue().get(key);
return JSON.parseObject(jsonString, tClass);
}
}
原因分析
RedisUtiles类中通过@Autowired注入了RedisTemplate,该操作是通过spring实现的注入。而new出来的类不受spring管理,RedisUtiles中的RedisTemplate无法完成注入,因此为空。
解决方法
统一都用Spring管理,或在new时不使用类中通过spring注入的成员变量