Design patterns 自定义Guice范围,还是更好的方法?
我的问题是: 首先要知道我在写一个模拟。这是一个独立的应用程序,是单线程的。我基本上有两类对象,它们具有不同的范围要求Design patterns 自定义Guice范围,还是更好的方法?,design-patterns,scope,guice,Design Patterns,Scope,Guice,我的问题是: 首先要知道我在写一个模拟。这是一个独立的应用程序,是单线程的。我基本上有两类对象,它们具有不同的范围要求 在整个模拟过程中应作为单例使用的类。随机的实例,例如 一起创建的类组,并且在组内,每个实例都应该被视为一个单例。例如,假设RootObject是顶级类,并且依赖于ClassA和ClassB,这两个类都依赖于ClassD。对于任何给定的RootObject,它的两个依赖项(ClassA和ClassB)都应该依赖于ClassD的同一个实例。但是,ClassD的实例不应在RootOb
RootObject
是顶级类,并且依赖于ClassA
和ClassB
,这两个类都依赖于ClassD
。对于任何给定的RootObject
,它的两个依赖项(ClassA
和ClassB
)都应该依赖于ClassD
的同一个实例。但是,ClassD
的实例不应在RootObject
的不同实例之间共享RootObject
实例时派生一个子注入器。然后,RootObject
的实例及其所有依赖项都作为单例创建,但是下次我去创建另一个RootObject
时,范围信息就会被丢弃
第二种方法是实现某种类型的自定义范围
Guice文档给出了相互矛盾的建议。。。一方面,它说您应该有一个单一的注入器,理想情况下,只需调用一次就可以创建一些顶级类。另一方面,它说远离自定义作用域。我可以问一下为什么需要单例吗 我不建议创建自定义范围。混合作用域的最佳且最简单的方法是注入提供程序而不是对象。通过提供程序,您可以从业务代码逻辑控制对象的范围
有关详细信息,请参见此。您是否考虑过使用提供商?编写一个符合您的要求的文档是很容易的,例如:
import com.google.inject.Provider
class RootObjectProvider implements Provider<RootObject> {
...
@Override
RootObject get() {
ClassD d = new ClassD( .... );
ClassB b = new ClassB( ..., d, ...);
ClassC c = new ClassC( ..., d, ...); // Note that b and c share d.
return new RootObject(b, c, ...);
}
}
import com.google.inject.Provider
类RootObjectProvider实现提供程序{
...
@凌驾
RootObject get(){
类别d=新的类别d(…);
ClassB=新的ClassB(…,d,…);
ClassC=新的ClassC(…,d,…);//注意,b和c共享d。
返回新的RootObject(b,c,…);
}
}
您可以通过两种方式使用提供程序:
@提供的
接口或.toProvider()
绑定装饰将其绑定为提供程序RootObject
实例希望这能有所帮助。在我看来,您需要为
RootObject
的每个实例及其所有依赖项提供一个作用域
在Guice中,您可以创建自定义范围,例如@ObjectScoped
,如下所示:
@Target({TYPE,METHOD})
@保留(运行时)
@范围注释
public@interface ObjectScoped{}
现在只需将RootObject
、A
、B
和D
放入此范围:
@ObjectScoped
公共类根对象{
私人A;
私人B,;
@注入
公共根对象(A、B){
这个a=a;
这个.b=b;
}
公共A getA(){
返回a;
}
公共B getB(){
返回b;
}
}
@对象范围
公共A类{
私家侦探;
@注入
公共事务A(D){
这个。d=d;
}
公共D getD(){
返回d;
}
}
//B和D也一样
现在,每个RootObject
都有自己的作用域。您可以将其实现为一个简单的HashMap
:
公共类ObjectScope{
私有映射,对象>();
@抑制警告(“未选中”)
公用T获取(密钥){
return(T)store.get(key);
}
公共无效集(密钥,T实例){
store.put(键、实例);
}
}
要将这些作用域与Guice集成,您需要一个com.google.inject.Scope
-实现,它允许您在模块中切换作用域和相应的连接
公共类GuiceObjectScope实现作用域{
//使其成为多线程的ThreadLocal。
私有ObjectScope current=null;
@凌驾
公共提供程序作用域(最终密钥,最终提供程序未作用域){
返回新的提供程序(){
@凌驾
公共部门得不到{
//查找实例
T instance=current.get(key);
if(实例==null){
//创建实例
instance=unscoped.get();
当前.set(键、实例);
}
返回实例;
}
};
}
public void enter(ObjectScope范围){
电流=范围;
}
公众假期{
电流=零;
}
}
公共类ExampleModule扩展了AbstractModule{
私有GuiceObjectScope objectScope=新的GuiceObjectScope();
@凌驾
受保护的void configure(){
bindScope(objectScope.class,objectScope);
//你的绑定
}
公共GUI对象范围getObjectScope(){
返回对象范围;
}
}
按如下方式初始化程序:
ExampleModule=newexampleModule();
喷油器喷油器=Guice.createInjector(模块);
GuiceObjectScope objectScope=module.getObjectScope();
创建RootObject
的第一个实例及其相应范围:
ObjectScope obj1=新的ObjectScope();
输入(obj1);
RootObject rootObject1=injector.getInstance(RootObject.class);
leave();
只需切换第二组对象的范围:
ObjectScop