如何从单例模式迁移到Spring?

迪特·范·德·沃尔

我目前正在研究大型非Spring代码库。我想将Spring Context引入代码库,但我想逐步做到这一点。

我要解决的第一个挑战之一是“ Springify”一个在代码中大量使用的大型单例对象。

在代码中使用单例,如下所示:

SomeInstance instance = SomeInstance.getInstance();
instance.doSomething()

单例对象包含如下字段和方法:

class SomeInstance {
    private static SomeInstance instance;

    public static SomeInstance getInstance(){
    if(instance == null){
        instance = new SomeInstance();
    }
    return instance;
}

好的,这行得通,但是我想将该SomeInstance设为Spring bean。

没问题:

@Component
class SomeInstance {
    ...
}

但是,我仍然希望保留getInstance()静态方法,并使其返回单例实例,以便向后兼容,而不必重构所有内容。如果我想摆脱getInstance()代码中各处方法,这意味着巨大的重构:

  • 制作所有使用SomeInstanceSpring bean的对象
  • 使用@Autowired连接单例

那太好了,但是我现在不能证明有这么大的重构理由。

但是,如何使它成为SomeInstanceSpring托管的并且仍然保持该getInstance()方法的向后兼容性呢?

我想到了这样的事情:

public static SomeInstance getInstance() {
    return ApplicationContext.getBean("someInstanceBean");
}

但是,getBean()可能无法从静态上下文中调用方法。

关于如何处理的任何想法?

雷德瓦尔德

在您的应用程序上下文XML文件中,您所需要做的就是编写类似于以下内容的条目:

<bean id="thing" name="thing" class="com.example.ThingSingleton"
    factory-method="getInstance">
</bean>

没有理由更改您现有的API。您现有的API要求声明或指定为单例的实际上是一个单例。那很好,值得保留。Spring是使用类的Plain Old Java API连接POJO的便捷方式,而不是构造函数,工厂方法等的替代方法。

完成此操作后,您可能会对自己说:“我的代码都不应该调用com.example.ThingSingleton.getInstance(),因此我应该将其标记为@Deprecated,这是使用Spring之前的一段遗迹”。但这是完全错误的。根本不建议使用该方法:明确告诉Spring使用它,这不是错误。该方法仍然是获得Singleton实例的唯一且唯一被批准的方法。只是恰巧没有代码,你编写调用它。不推荐使用并不意味着“未在我的代码中使用”。这意味着“不应使用,因为将来可能会删除它”。您不会删除该getInstance()方法,对吗?

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章