【发布时间】:2016-11-14 15:48:16
【问题描述】:
像这样上课:
public class A {
@Inject B b;
@Inject C c;
}
是否可以告诉 Weld 不要注入到 c 中?我可以使用事件否决 A 类:
<T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> pat)
但是 B 对象也不会被注入。我正在寻找类似的东西:“如果类名是 A 并且字段类型是 C 则省略注入。”
更具体地说,我希望 HK2 引擎注入“C”字段,问题是 HK2 和 Weld 都使用 @Inject 注释。
Siliarus 解决方案:
我尝试了 Siliarus 解决方案。我找到了我想要添加自定义注入实现的类型:
<T> void processIT(@Observes ProcessInjectionTarget<T> pat, BeanManager beanManager) {
Set<InjectionPoint> injectionPoints = pat.getInjectionTarget().getInjectionPoints();
for (InjectionPoint injectionPoint : injectionPoints) {
if (injectionPoint.getType().equals(B.class)) {
l.info("Adding CustomInjection to {}", pat.getAnnotatedType().getJavaClass());
pat.setInjectionTarget(new CustomInjection<T>(pat.getInjectionTarget(), beanManager));
}
}
}
}
}
在我在 CustomInjection 中添加了覆盖的注入(...)之后
public CustomInjection(InjectionTarget<T> originalInjectionTarget, BeanManager beanManager) {
this.wrappedInjectionTarget = originalInjectionTarget;
this.beanManager = beanManager;
}
喜欢:
@Override
public void inject(T instance, CreationalContext<T> ctx) {
l.trace("Injecting into {}", instance);
//....create my own HK2 object. Can it be just new B() for example ?!
locator =ServiceLocatorUtilities.createAndPopulateServiceLocator();
B b = locator.createAndInitialize(B.class);
l.trace("First injecting standard dependencies {}", instance);
wrappedInjectionTarget.inject(instance, ctx);
// dispose created by CDI B type object ?! - seems messy but works
manageBViaReflection((x, y, z) -> x.set(y, z), instance, b);
}
在 manageBViaReflection 中,我只是将对象 B - b 设置为类型 B 的字段 X 和实例 Y - 实例上的名称 b。
微妙的不准确之处在于:
wrappedInjectionTarget.inject(instance, ctx);
在 B 上执行和 CDI 注入。我有生产者来键入 B,但我想在这个特定的类中自己创建它 - 不使用生产者。对象 B 必须被处置,当我使用 manageBViaReflection 覆盖它的值时,我必须先处置它——它有点混乱,但通常这个想法是有效的。
Siliarus,jwells131313 - 也许你还有什么建议?
【问题讨论】:
-
谁在创建 A 类、焊接 (CDI) 或 HK2?如果你不知道,你可以在 A 的构造函数中打印一个堆栈跟踪(或放置一个断点)来弄清楚
-
A 由 CDI 创建。
-
@maciek 我不确定现在有什么问题?首先,为什么需要
manageBViaReflection?其次,I have producer to type B- 为什么?你不希望 CDI 生产这个,你自己做,不是吗?如果它的 CDI 层次结构让您感到困惑 (InjectionTarget extends Producer),那么请注意,在这种情况下,Producer<T>不是经典的@Produces,请参阅其javadoc 了解更多信息。 -
好吧,忘记 B 的制作人——我确实想自己制作。那么如何将字段 B b 设置为 A 类中自定义生成的对象(我想将其设置在那里,对吗?)据我所知,当 B b 引用上方存在 @Inject 注释时会调用
public void inject(T instance, CreationalContext<T> ctx)?这意味着如果存在@Inject,那么 Weld 会检查它是否能够在部署阶段执行注入。如果我没有 @Inject B b 则不会调用inject(T instance, CreationalContext<T> ctx)并且我无法生成和设置我自己的对象。 -
您能否提供遵循您的想法的方法
public void inject(T instance, CreationalContext<T> ctx)的示例伪代码实现?让我们假设对象 B 在 inject(...) 的开头已经以某种方式创建了。我应该如何在这个 inject(...) 方法中将对象 B 注入到 T 实例中?也许我错过了一些明显的功能?
标签: java dependency-injection cdi weld hk2