如何协助非辅助依赖?

Kel*_*ung 6 java guice assisted-inject

假设我有第三方课程如下:

public class MyObject {
    @Inject
    public MyObject(Foo foo, Bar bar) { ... }
}
Run Code Online (Sandbox Code Playgroud)

现在假设我有一个像这样的工厂界面:

public interface MyObjectFactory {
    public MyObject build(Bar bar);
}
Run Code Online (Sandbox Code Playgroud)

我的想法是,我希望有一个MyObjectFactory构建一个MyObject固定的Foo- 也就是说,实质上是从外部添加构造函数参数的@Assisted注释Bar.当然,手动实现MyObjectFactory总是可行的:

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

    @Override
    public MyObject build(Bar bar) { return new MyObject(foo.get(), bar); }
}
Run Code Online (Sandbox Code Playgroud)

但是,让我们说有条件要求我使用Guice构建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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这听起来很邪恶,并且是锅炉板,所以我想知道是否有任何替代实施和/或让Guice产生工厂impl的方法.

dur*_*597 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,使用我上面描述的命名约定删除对整个代码的所有引用MyObject,应该只引用MyWrapperInterface.