gpt4 book ai didi

java - CDI Weld 省略 @Inject

转载 作者:行者123 更新时间:2023-11-30 10:36:26 25 4
gpt4 key购买 nike

像这样上课:

public class A {
@Inject B b;
@Inject C c;
}

是否可以告诉 Weld 不要注入(inject)到 c 中?我可以使用事件否决 A 类:

<T> void processAnnotatedType(@Observes  ProcessAnnotatedType<T> pat) 

但是 B 对象也不会被注入(inject)。我正在搜索类似这样的内容:“如果类名是 A 并且字段类型是 C,则忽略注入(inject)。”

更具体地说,我希望 HK2 引擎注入(inject)“C”字段,问题是 HK2 和 Weld 都在使用 @Inject 注释。

Siliarus 解决方案:

我尝试了 Siliarus 解决方案。我找到了我想要添加我的自定义注入(inject)实现的类型:

<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 中添加了覆盖的注入(inject)(...)

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 注入(inject)。我有生产者来键入 B,但我想在这个特定的类中自己创建它——不使用生产者。对象 B 必须被处置,当我使用 manageBViaReflection 覆盖它的值时,我必须首先处置它——它有点困惑,但通常这个想法是可行的。

Siliarus,jwells131313 - 也许你有任何进一步的建议?

最佳答案

好的,从 Weld/CDI 的角度来看,这里是如何禁用对这些区域的注入(inject)。请注意,我不知道 HK2,所以我不知道你想如何将它链接到那里,但从 CDI 的角度来看,你需要将 bean 作为 @Dependent。 (以避免在事情变得更糟糕的地方代理)。您还没有指定 CDI 的版本,所以我会为 1.x 和 2.0 都做注释。

实际上我想到的是两件事,首先,它是 ProcessAnnotatedType阶段,您可以在其中删除@Inject 注释,以便当 CDI 采用该注释类型(它变成 bean)时,它将不再将其视为注入(inject)点。你会这样做:

void processAnnotatedType(@Observes  ProcessAnnotatedType<T> pat) {
pat.configureAnnotatedType().remove(Inject.class); // CDI 2.0 solution
// for CDI 1.x you need to implement your own AT, which
// will do just the same, the call this:
// pat.setAnnotatedType(yourOwnAT);
}

其次考虑了 ProcessInjectionTarget .你需要包装 InjectionTarget用你自己的实现。这种方法的优势在于您可以直接在此处 Hook HK2 内部结构。主要思想是覆盖 javax.enterprise.inject.spi.InjectionTarget.inject(T, CreationalContext<T>)并将 HK2 代码放在这里,所以当 CDI 实际尝试进行注入(inject)时,它会使用 HK2。

void processIT(@Observes  ProcessInjectionTarget<T> pat) {
pat.setInjectionTarget(myITImpl); // just set your wrapped impl here
// there is no diff here in CDI 1.x and 2.0, no configurator here
}

无论您选择哪种方式,请记住 CDI 有大量的 TCK tests它涵盖了所有这些内容,因此可以用作示例来了解如何实现此类包装器。

关于java - CDI Weld 省略 @Inject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40592677/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com