Spring不支持依赖注入static静态变量
在springframework里,我们不能@Autowired一个静态变量,使之成为一个spring bean,例如下面这样:
@Autowired
private static YourClass yourClass;
可以试一下,yourClass在这种状态下不能够被依赖注入,会抛出运行时异常java.lang.NullPointerException
,为什么呢?因为静态变量/类变量不是对象的属性,而是一个类的属性,spring则是基于对象层面上的依赖注入。
Spring如何给静态变量注入值
1. set方法上添加@Autowired注解,类定义上添加@Component注解
@Component
public class MoneyOperationUtil {
private static Bank bank;
@Autowired
public void setBank(Bank bank) {
MoneyOperationUtil.bank= bank;
}
}
首先Spring要能扫描到MoneyOperationUtil 的bean,然后通过setter方法注入。
需要注意的是:
- 静态成员变量上不需要再添加@Autowired注解。
- 虽然你添加了@Component 这个标签在工具类上,但是你必须保证spring在加载配置文件的时(application-*.xml),其中要有配置文件开启了你工具类所在的包的注解。
- 如果你需要注入的静态变量是spring未知的类(非基本数据类型和string、以及非注解过的类(@Component、@controller、@service、@repository)),也需要让spring管理到,就是要在spring加载的某个application-*.xml文件中配置bean。
- 静态变量的setter方法的static关键字要去掉,不然会注入失败。
2. xml方式实现
<bean id="moneyOperationUtil" class="com.*.*.MoneyOperationUtil" init-method="init">
<property name="bank" ref="bank"/>
</bean>
public class MoneyOperationUtil{
private static Bank bank;
private static MoneyOperationUtil moneyOperationUtil;
public void init() {
moneyOperationUtil = this;
moneyOperationUtil.bank = this.bank;
}
}
3. @PostConstruct方式实现
@Component
public class MoneyOperationUtil{
@Autowired
private static Bank bank;
private static MoneyOperationUtil moneyOperationUtil;
@PostConstruct
public void init() {
moneyOperationUtil = this;
moneyOperationUtil.bank= this.bank;
}
}
@PostConstruct 注解的方法在加载类的构造函数之后执行,也就是在加载了构造函数之后,执行init方法。这种方式和在xml中配置 init-method和 destory-method方法差不多,定义spring 容器在初始化bean和容器销毁之前的所做的操作。