静态方法无法调用通过@Autowired注入的Service对象
需求
需要将某个方法抽离至utils工具类中,并修饰为static静态方法,由于工具类中方法一般都是静态的,所以要求该属性也要是静态的。
问题
通过 @Autowired 或 @Resource 都无法注入成功,Service对象一直都是 null
原因
由于Spring/SpringBoot正常情况下不能支持注入静态属性(会报空指针异常)。
主要原因在于:
- Spring的依赖注入实际上是依赖于Set方法进行注入值的,Spring是基于对象层面的依赖注入,而静态属性/静态变量实际上是属于类的。
可能存在的原因:
-
该类没有托管给spring 管理,一般在类的上面添加@Component
-
你的这个类有被new出来的实例的,new 过的对象不会交给Spring容器管理 所以里面的 service或者dao注入不进来。一般是指引用某些框架,你是继承某个接口,但是这些框架默认new过这个方法,比如MVC拦截的HandlerInterceptor类。
解决方案
创建一个组件配置类,实现ApplicationContextAware接口,用于手动注入。 必须用@Component 注解
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class BeanUtils implements ApplicationContextAware {
protected static ApplicationContext applicationContext ;
@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
if (applicationContext == null) {
applicationContext = arg0;
}
}
public static Object getBean(String name) {
//name表示其他要注入的注解name名
return applicationContext.getBean(name);
}
/**
* 拿到ApplicationContext对象实例后就可以手动获取Bean的注入实例对象
*/
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
}
在utils类中,手动注入
/**
* 由于不能用@Autowired进行注入,则使用这种手动注入方式
*/
private static RedisTemplate redisTemplate = BeanUtils.getBean(RedisTemplate.class);
这样就可以正常引用redisTemplate,这样手动出来的跟@Autowire 一样的。
Set keys = redisTemplate.keys("PRODUCT*");