静态方法中调用@Autowired
2022-01-26 20:52 话猫 阅读(2143) 评论(0) 收藏 举报一、背景
1.今天写代码发现有一个使用@Component注解的util类,类中的方法都是static静态修饰的,但是我要修改其中一个静态方法,在静态方法中我要调用一个service类,代码如下
修改前:
@Component
@Slf4j
public class TestUtil {
private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test";
public static List<Integer> get() {
return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer.class, ImmutableList.of(2, 5, 7, 14, 16));
}
}
修改后
@Component
@Slf4j
public class TestUtil {
private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test";
private static final String SWITCH = "switch";
@Autowired
private static JobNeedCarrierQuery jobNeedCarrierQuery;
public static List<Integer> get() {
if(Lion.getBooleanValue(SWITCH)) {
return jobNeedCarrierQuery.doQuery();
}else {
return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer.class, ImmutableList.of(2, 5, 7, 14, 16));
}
}
}
二、问题
当执行修改后的代码后,发现报了空指针异常,debug发现jobNeedCarrierQuery没有被注入对象,调用doQuery方法是报NPE
三、原因
在 Java 中,针对 static 静态成员,我们有一些最基本的常识:静态变量(成员)它是属于类的,而非属于实例对象的属性;同样的静态方法也是属于类的,普通方法(实例方法)才属于对象。而 Spring 容器管理的都是实例对象,包括它的@Autowired依赖注入的均是容器内的对象实例,所以对于 static 成员是不能直接使用@Autowired注入的。这很容易理解:类成员的初始化较早,并不需要依赖实例的创建,所以这个时候 Spring 容器可能都还没“出生”,谈何依赖注入呢?
四、解决方案
2.@PostConstruct方式实现
@Component (1)
@Slf4j
public class TestUtil {
private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test";
private static final String SWITCH = "switch";
@Autowired. (2)
private JobNeedCarrierQuery jobNeedCarrierQuery;
private static TestUtil testUtil; (3)
@PostConstruct (4)
public void init(){
testUtil = this;
testUtil.jobNeedCarrierQuery = this.jobNeedCarrierQuery;
}
public static List<Integer> get() {
if(Lion.getBooleanValue(SWITCH)) {
return testUtil.jobNeedCarrierQuery.doQuery(BusinessLineEnum.SPOCK_BIKE.getCode()); (5)
}else {
return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer.class, ImmutableList.of(2, 5, 7, 14, 16));
}
}
}
3.set方法上添加@Autowired注解,类定义上添加@Component注解
@Component
public class TestUtil {
private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test";
private static final String SWITCH = "switch";
private static JobNeedCarrierQuery jobNeedCarrierQuery;
@Autowired
public void setDatastore(JobNeedCarrierQuery jobNeedCarrierQuery) {
TestUtil.jobNeedCarrierQuery=jobNeedCarrierQuery;
}
public static List<Integer> get() { if(Lion.getBooleanValue(SWITCH)) { return jobNeedCarrierQuery.doQuery(); }else { return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer.class, ImmutableList.of(2, 5, 7, 14, 16)); } }
}
浙公网安备 33010602011771号