考虑这段代码:
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 需要 Spring bean 进行构建时,我该如何做同样的事情?我不想在每个需要它的类中注入(inject) A,但希望这些类能够静态访问单例实例(即 A.getInstance()
)。
最佳答案
从静态上下文访问 Spring bean 是有问题的,因为 bean 的初始化与其构造无关,并且 Spring 可能通过将注入(inject)的 bean 包装在代理中来检测它们;简单地传递对 this
的引用通常会导致意外的行为。最好依靠Spring的注入(inject)机制。
如果您确实必须这样做(可能是因为您需要从遗留代码进行访问),请使用如下内容:
@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();
}
}
关于java - 在 Spring 中使用 Java 单例模式(静态访问单例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29423958/