Java 如何在不破坏Guice AOP方法拦截的情况下,在Guice注入中提供参数?
我有一种情况,我需要使用Guice 3.0来实例化我的对象,但其中一个值可能会随着每个实例而改变。我无法绑定该值的类型,在需要创建实例之前我不知道 例如:Java 如何在不破坏Guice AOP方法拦截的情况下,在Guice注入中提供参数?,java,aop,guice,factory-pattern,Java,Aop,Guice,Factory Pattern,我有一种情况,我需要使用Guice 3.0来实例化我的对象,但其中一个值可能会随着每个实例而改变。我无法绑定该值的类型,在需要创建实例之前我不知道 例如: public class Foo { public Foo(Bar bar, Baz baz) {...} } 我想让Guice插入条参数,但在需要Foo之前,我不知道Baz。该值也不是特定于范围的(例如RequestScope) 我希望这个对象完全由Guice实例化的全部原因是因为我需要方法拦截。在Guice中,“手动构造的实例不
public class Foo {
public Foo(Bar bar, Baz baz) {...}
}
我想让Guice插入条
参数,但在需要Foo
之前,我不知道Baz
。该值也不是特定于范围的(例如RequestScope)
我希望这个对象完全由Guice实例化的全部原因是因为我需要方法拦截。在Guice中,“手动构造的实例不参与AOP”
我曾尝试使用提供程序
执行此操作,但这只允许我使用public Foo get(){…}
必须为Baz
的每个可能值创建一个提供程序,这将是一个配置噩梦,因此我不能简单地在FooProvider的构造函数中定义Baz
我觉得我错过了一些基本的东西。也许是因为这是我在周五做的最后一件事。任何想法都将不胜感激
编辑:下面使用“辅助注射”的答案似乎只有在您能够编辑Foo
的源代码时才有效<代码>Foo在某些情况下实际上可能超出我的控制范围。如果我自己创建实例(即实现我自己的工厂),那么Guice AOP方法拦截器似乎永远都不知道该对象。看起来“辅助注入”可能是一个解决方案:
除非如果您没有权限对Foo
的构造函数进行注释,否则它将不起作用
编辑:我发现我可以通过扩展类型并将它们添加到我希望使用的构造函数中来添加辅助注入注释:
public class AssistedFoo extends Foo {
@AssistedInject
public AssistedFoo(
Bar bar,
@Assisted Baz baz) {
super(bar, baz);
}
}
然后在辅助注射注册中使用此扩展实现:
public interface FooFactory {
Foo create(Baz baz);
}
//...
install(new FactoryModuleBuilder()
.implement(Foo.class, AssistedFoo.class)
.build(FooFactory.class));
只有当您无权更改
Foo
时,才需要额外的继承类。显然,如果类是final
的话,这种变通方法就不起作用了。如果您不能使用辅助注入来创建工厂,您可以编写自己的工厂实现:
// same as for Assisted Inject
public interface FooFactory {
Foo createFoo(Baz baz);
}
public class FooFactoryImpl implements FooFactory {
private final Bar bar;
@Inject
public FooFactoryImpl(Bar bar) {
this.bar = bar;
}
public Foo createFoo(Baz baz) {
return new Foo(bar, baz);
}
}
然后只需将(FooFactory.class.)绑定到(FooFactoryImpl.class)并在需要创建Foo
s的任何位置注入FooFactory
编辑:
您可以做一个非常尴尬的变通方法(这将允许方法拦截Foo
):
bind(Foo.class).toConstructor(…)
- 定义并绑定所述的
范围SimpleScope
bind(Baz.class).in(BatchScoped.class)
- 将
和提供程序
注入到要创建SimpleScope
s的类中Foo
如果方法不是
私有的
,您甚至可以对此类方法使用方法拦截来处理作用域。。。虽然这可能不是一个好主意,因为如果您根本不在方法中使用参数,这会让人困惑,但它必须在那里工作。如果我无法将@辅助的注释添加到Baz
参数,该怎么办?e、 g.当我不控制Foo
的源代码时,只需编写自己的FooFactory
类,将Bar
注入其中,然后让它公开一个采用Baz
参数的方法。然后,该方法可以返回新的Foo(bar,baz)
。辅助注入所能做的(或多或少)就是使您不必编写直接的实现。这实际上回到了我开始时的情况,但Guice不允许在它没有创建的对象上使用方法拦截器(Guice AOP)。看起来我可能会遇到两个特性的限制冲突的情况。是的,听起来你可能有。我更新了我的答案,提出了一个解决方案,如果你真的需要让方法拦截工作起来,你可以尝试。范围的有趣用法。对其他人来说似乎有点沉重和/或难以跟随。这表明Guice的人可能有机会在这里添加一些机制。@McCamey:是的,我认为这是一个相当丑陋的黑客行为!我认为一个更好的解决方案是在Foo
上不能使用方法拦截。其中一个选项可能是创建您自己的(可拦截和辅助注入)类来包装Foo
,并公开您需要的方法。如果您查看另一个答案,我可以通过从Foo
导入来获得辅助注入。这使我能够控制构造函数注释。@McCamey:是的,对于任何可以扩展的类来说,这都是一个很好的解决方案。
public Foo someMethod(Baz baz) {
simpleScope.enter();
try {
simpleScope.seed(Baz.class, baz);
/*
* We're in the scope for Baz, so it can be injected normally into Foo
* right now.
*/
return fooProvider.get();
} finally {
scope.exit();
}
}