在我们实际开发的过程中经常会用到单例类、或自己调用 new 关键字创建的对象。而很多新手由于对自动注入的机制并不了解,因此会尝试使用 @Autowired 注解来自动注入一个对象到单例类中。
由于单例类不是通过自动注入来创建的,因此,也不受Spring容器管理。而此时使用 @Autowired 注解自动注入一个对象时,这个对象肯定会是null。这是因为Spring容器的机制导致的。错误的代码如下:
public class CurrencyUtil {
@Autowired
MidPointRatioRepository midPointRatioRepository;
private static CurrencyUtil ourInstance = new CurrencyUtil();
public static CurrencyUtil getInstance() {
return ourInstance;
}
private CurrencyUtil() {
}
}
而下面👇则是本文想要分享的,如何在非自动注入对象中访问受Spring管理的自动注入对象。
首先,你的类需要实现 ApplicationContextAware 接口,其次,实现 setApplicationContext 方法,然后将参数中的 ApplicationContext 保存为成员变量。
之后,在希望获取自动注入对象的时候,就可以通过 ApplicationContext 类的 getBean 方法获取了。在我的代码中我将获取自动注入对象的方法包装成了一个函数,并且使用double-check的方法来获取,避免多线程并发冲突。
public class CurrencyUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
private static volatile MidPointRatioRepository midPointRatioRepository = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if(CurrencyUtil.applicationContext == null){
CurrencyUtil.applicationContext = applicationContext; //初始化 spring applicationContext
}
}
private MidPointRatioRepository getMidPointRatioRepository() {
if (midPointRatioRepository == null) {
synchronized (MidPointRatioRepository.class) {
if (midPointRatioRepository == null) {
midPointRatioRepository = applicationContext.getBean(MidPointRatioRepository.class);
}
}
}
return midPointRatioRepository;
}
private static CurrencyUtil ourInstance = new CurrencyUtil();
public static CurrencyUtil getInstance() {
return ourInstance;
}
private CurrencyUtil() {
}
}
以上,就是全部内容,希望对你能有所帮助。