1.问题:
在静态方法中需要使用spring注入的对象,但是在运行使用过程中,此对象则是为null,所以会导致空指针异常
正常写的代码(咋一看是没啥毛病吧):
@Autowired
private static RedisTemplate<String, Object> redisTemplate;
public static long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
但是,此时的redisTemplate对象为null(这就尴尬了,对象咋没了,肯定是没注入进来,那是什么原因呢?)
嗯,那是因为静态方法是属于类的,而普通方法则属于对象,spring注入只在容器中实例化变量的,并且静态是优先于对象存在的,所以直接在静态方法中调用注入的静态变量其实是null的。(那么问题来了,该如何解决呢?请看下面)
2.解决方法:
a.用@Autowired注解加载构造函数上
我们知道@Autowired 注释,可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作,此种方式就是在构造函数上使用@Autowired。
代码如下:
private static RedisTemplate<String, Object> redisTemplate;
@Autowired
public RedisUtils(RedisTemplate<String, Object> redisTemplate) {
RedisUtils.redisTemplate = redisTemplate;
}
public static long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
此时redisTemplate对象是存在值的
b.使用@PostContruct注解,来给所需要的静态对象赋值
@PostConstruct是Java EE 5引入来影响Servlet生命周期的注解,被用来修饰非静态的void()方法,
@PostConstruct在构造函数之后执行,init()方法之前执行。
代码如下:
@Autowired
RedisTemplate<String, Object> redisTemplate;
private static RedisUtils redisUtils;
@PostConstruct
public void init(){
redisUtils = this;
redisUtils.redisTemplate = this.redisTemplate;
}
public static boolean set(String key, Object value) {
try {
redisUtils.redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
而此时静态方法中则使用redisUtils.redisTemplate去调用对应的方法