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

标签 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 需要 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/

相关文章:

java - 如何在嵌套的 for 循环完成后运行 if 语句?

java - 升级 spring-boot-1.5.20 -> spring-boot-2.1.4 后出现 Spring Data 性能问题

Spring Cloud Config Server 跨应用程序共享属性

java - 如何从 Groovy Spring 注入(inject)我的 Controller 层

java - 在java中提取已知模式的子串

java - java中访问资源的不同字符串

java - SourceDataLine 跳过指定数量的字节(JavaSound)

java - 单例与静态变量

java - @DirtiesContext 在每个 cucumber 测试场景之后撕下上下文,而不是类

java - 交易后刷新实体