我有一些严重的问题要理解,如何使用依赖注入,尤其是多线程环境中的单例设计模式。
让我说我有一个班级:
public class DependencyOne {
private DependencyTwo dependencyTwo;
private DependencyThree dependencyThree;
private Integer aNumber;
public Foo(Integer aNumber, DependencyTwo dependencyTwo, DependencyThree dependencyThree) {
this.aNumber = aNumber;
this.dependencyTwo = dependencyTwo;
this.dependencyThree = dependencyThree;
}
public doSomething() {
dependencyTwo.doSomethingInDepOne(aNumber, dependencyThree);
}
}
public class DependencyTwo {
private DependencyThree dependencyThree;
private aNumber;
public Foo(Integer aNumber,DependencyThree dependencyThree) {
this.aNumber = aNumber;
this.dependencyThree = dependencyThree;
}
public doSomething() {
dependencyThree.doSomethingInDepOne(aNumber);
}
}
public class Main {
public static void main(String[] args) {
DependencyOne depTwo = new DependencyTwo("foo", "foofooo" .... <- just random config);
DependencyOne depThree = new DependencyThree(1,2,3,4,5,12,3,1235 <- just random config);
DependencyOne depOne = new DependencyOne(123, depTwo, depThree);
depOne.doSomething();
}
}
现在让我们想象一下,DependencyThree由于各种原因需要是一个单身人士,例如: JPA EntityManagerFactory,集中日志记录或全局级别的任何内容,而不是每个线程。
Injector injector = Guice.createInjector(new DependencyThree());
据我所知,注射器只能创建一次。
现在我的问题是,提供对DependencyThree类的一个实例的访问的最佳方法是什么。
**
我不希望将dependencythree对象传递给所有其他对象 课程,以获取它。
**
目前我刚刚创建了一个全局单例,当我要求时,它会返回实例。 但有些人说,这是非常糟糕的设计,(是吗?)。 我如何使用依赖注入,在此设置上,或者根本不应该使用它?这段代码只是被强奸了一下,它通常在多线程环境中运行。
Guice提供@Singleton注释,但这是每个线程而不是多线程。
如何在Guice中实现一个全局单例,这是懒惰创建的?
答案 0 :(得分:3)
@Singleton
表示一旦创建了目标类的实例,就会为所有后续注入请求返回相同的实例。注入器本身是线程安全的,因此可以在线程之间安全地共享。
现在,注射何时发生?当您要求Guice获取实例而不是自己使用new
运算符时,就会发生注入。
您只需要确保没有循环依赖关系,并且注入对象的生命周期明确定义为{<1}}实例创建之前取决于类并且可能被破坏的后即可。顺便说一句,单身人士概念本身没有任何问题:有时你只是拥有一个物理资源,而这个物理资源不能在实例上代表。它是带有Java @Singleton
的单例模式和延迟加载,它经常被批评,因为它实现起来有点不重要,而且有更安全的替代方案(如依赖注入框架)