将依赖项注入Singleton类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将依赖项注入Singleton类相关的知识,希望对你有一定的参考价值。
我有一个像这样定义的单例实例:
public class Singleton {
private static Singleton INSTANCE = new Singleton();
private Singleton() {
}
public Singleton getInstance() {
return INSTANCE;
}
}
现在,由于一些更改,此类必须依赖于一些(3)依赖项。因此,必须在此处注入这些依赖项。
我们如何为这样设计的Singleton类实现依赖注入?
问题是Singleton.getInstance()
上已有很多调用者,因此无法使getInstance方法接受依赖项。
P.S:我明白使用Singletons并不总是更清洁的方式:)(这是现有的代码,我必须忍受它:))
P.S:我正在使用Guice进行依赖注入。
您可以将您的类重构为依赖项,同时为客户端保留相同的API。 以Spring为例:
@Component
public class Singleton {
private Foo foo;
private Bar bar;
private Any any;
// inject dependencies
@Autowired
// annotation not required in recent Spring versions
public Singleton (Foo foo, Bar bar, Any any){
this.foo = foo;
this.bar = bar;
this.any = any;
}
public Singleton getInstance() {
return this;
}
}
从客户端,如果客户端类不是bean,则可以注入bean或从bean容器中检索它。
从bean类访问的示例:
public class SingletonClient{
@Autowired
private Singleton singleton;
public void foo(){
singleton.getInstance().method();
}
}
避免客户类更改的想法。 免责声明:我不推广这种方式,因为它既反直觉,又容易出错,最重要的是保持单身人士静态访问的技术债务。 作为临时解决方案是可以接受的,但是应该尽快执行现有代码的重构。
因此,想法是在构造函数调用期间将bean实例存储在静态字段中。
通过这种方式,Singleton.getInstance()
返回豆。
@Component
public class Singleton {
private Foo foo;
private Bar bar;
private Any any;
private static Singleton instance;
// inject dependencies
@Autowired
// annotation not required in recent Spring versions
public Singleton(Foo foo, Bar bar, Any any) {
this.foo = foo;
this.bar = bar;
this.any = any;
instance = this;
}
public static Singleton getInstance() {
return instance;
}
}
您可以在Guice中使用@Singleton注释来告诉注入器只创建一个在应用程序中共享的实例。然后,您可以通过注释变量或选择的构造函数以通常的方式注入依赖项
@Singleton
public class Singleton {
@Inject // Choose to put the annotation here OR on a constructor, not both
private Foo foo;
@Inject // only put this constructor here if you don't annotate the variable
public Singleton (Foo foo){
this.foo = foo;
}
public Singleton getInstance() {
return this;
}
...
}
如果您使用Spring,即使没有公共构造函数,也可以实现依赖注入。只需标记依赖关系@Autowired。 Spring将通过反射注入它们。 :)
你可以这样做。
public class Singleton {
private DependencyClass1 dependency1;
private DependencyClass2 dependency2;
private DependencyClass3 dependency3;
private static Singleton INSTANCE = new Singleton(
new DependencyClass1(...),
new DependencyClass2(...),
new DependencyClass3(...)
);
private Singleton(
DependencyClass1 dependency1,
DependencyClass2 dependency2,
DependencyClass3 dependency3
) {
this.dependency1 = dependency1;
this.dependency2 = dependency2;
this.dependency3 = dependency3;
}
public Singleton getInstance() {
return INSTANCE;
}
}
它与任何IOC容器相同。
如果所有注入的依赖项都有单例作用域,则可以执行此操作,否则每次需要时都需要创建注入类的实例。
有将Protype Beans注入Singleton Beans的例子:
https://stackoverflow.com/a/25165971/3058413
以上是关于将依赖项注入Singleton类的主要内容,如果未能解决你的问题,请参考以下文章
Blazor University (48)依赖注入 —— Scoped 依赖
spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段