2015-06-26 35 views
6

假设我有一个第三方类,如下所示:如何帮助辅助依赖项?

public class MyObject { 
    @Inject 
    public MyObject(Foo foo, Bar bar) { ... } 
} 

现在假设我有一个工厂接口,像这样:

public interface MyObjectFactory { 
    public MyObject build(Bar bar); 
} 

的想法是,我希望有一个MyObjectFactory是建立一个MyObject对于固定的Foo - 也就是说,从外部实质上在注解对Bar构造函数参数添加。当然,手动执行MyObjectFactory始终是可能的:

public class MyObjectFactoryImpl implements MyObjectFactory { 
    @Inject private Provider<Foo> foo; 

    @Override 
    public MyObject build(Bar bar) { return new MyObject(foo.get(), bar); } 
} 

但是,让我们说,有需要我有吉斯建立MyObject实例条件 - 例如,方法拦截器。这似乎是对“注射进样器”的作业:

public class MyObjectFactoryImpl implements MyObjectFactory { 
    @Inject private Injector injector; 

    @Override 
    public MyObject build(Bar bar) { 
     Injector child = injector.createChildInjector(new AbstractModule() { 
      @Override 
      protected void configure() { 
       bind(Bar.class).toInstance(bar); 
       // Set up method interceptors for MyObject here... 
      } 
     }); 
     return child.getInstance(MyObject.class); 
    } 
} 

这听起来很邪恶,锅炉板,Y,所以如果有任何替代实现方式和/或办法有吉斯产生我想知道工厂impl。

回答

1

首先,这是罕见的,你想成为合格的MyObject情况下在你的班上周围正是您所描述的原因。你无法控制它们,所以你不能添加@Assisted注释,你不能添加方法拦截器等。另外,当你想换出不同的实现的第三方库时会发生什么?

因此,您应该将MyObject包装到另一个对象中。

// **Please** choose better names than this in your real code. 
public class MyWrapperBackedByMyObject implements MyWrapperInterface { 
    private final MyObject delegate; 

    @Inject 
    MyWrapperObject(Foo foo, @Assisted Bar bar) { 
     delegate = new MyObject(foo, bar); 
    } 

    @NotOnWeekends // Example of how you might do method interception 
    public void orderPizza() { 
     delegate.orderPizza(); 
    } 
} 

然后,取出到MyObject所有引用整个代码,使用的命名约定我上面描述,应该只有引用MyWrapperInterface

-1

实际上是。看看Assisted Inject

包括

 <dependency> 
      <groupId>com.google.inject.extensions</groupId> 
      <artifactId>guice-assistedinject</artifactId> 
      <version>${guice.version}</version> 
     </dependency> 

更新注射辅助

public class MyInjectedObject extends MyObject implements MyIntf { 
@Inject 
public MyObject(Foo foo, @Assisted Bar bar) { super(foo,bar); } 
} 

你必须增加一个接口:

public interface MyIntf {} 

在你的模块绑定通用的工厂到您界面

install(new FactoryModuleBuilder() 
      .implement(MyIntf.class, MyInjectedObject.class) 
      .build(MyObjectFactory.class) 
); 

现在你可以在任何你想要的地方注入MyObjectFactory。所有的

MyObject obj = myObjectFactory.build(bar); 
+0

同样,由于'MyObject'是第三方,我不能修改'MyObject';否则我只能使用普通的老式辅助注射。 –

+1

将它包裹到另一个对象中。 –