如何在单例中访问自动注入对象

799 阅读1分钟

在我们实际开发的过程中经常会用到单例类、或自己调用 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() {
    }
}

以上,就是全部内容,希望对你能有所帮助。