在Spring中使用Java单例模式(对单例的静态访问)

时间:2015-04-02 23:08:36

标签: java spring

考虑以下代码:

public class A {
    private static final A INSTANCE = new A();
    public static A getInstance() {
        return INSTANCE;
    }
    private A() {}
    public void doSomething() {}
}

// elsewhere in code
A.getInstance().doSomething();

当A需要弹簧豆进行施工时,我该如何做同样的事情?我不想在每个需要它的类中注入A,但希望这些类能够静态访问单例实例(即A.getInstance())。

1 个答案:

答案 0 :(得分:1)

从静态上下文访问Spring bean是有问题的,因为bean的初始化并不与它们的构造相关联,而Spring可以通过将它们包装在代理中来注入bean。简单地传递对this的引用通常会导致意外行为。最好依靠Spring的注射机制。

如果您确实 (可能是因为您需要从遗留代码访问),请使用以下内容:

@Service
public class A implements ApplicationContextAware {

    private static final AtomicReference<A> singleton;
    private static final CountDownLatch latch = new CountDownLatch(1);

    @Resource
    private MyInjectedBean myBean; // inject stuff...

    public static A getInstance() {
        try {
            if (latch.await(1, TimeUnit.MINUTES)) {
                return singleton.get();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        throw new IllegalStateException("Application Context not initialized");
    }

    @Override
    public void setApplicationContext(ApplicationContext context) {
        singleton.set(context.getBean(A.class));
        latch.countDown();
    }
}