拥有这样的类:
public class A {
@Inject B b;
@Inject C c;
}有没有可能告诉Weld不要注入到c中?我可以使用event来否决一个类:
<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));
}
}
}
}
}在我添加overrided inject之后(...)在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- instance上命名为b。
微妙的不准确之处在于这一行:
wrappedInjectionTarget.inject(instance, ctx);在B上执行和CDI注入。我将producer设置为类型B,但我想在这个特定的类中自己创建它--而不是使用producer。对象B必须被释放,当我使用manageBViaReflection覆盖它的值时,我必须首先释放它-这有点混乱,但通常这个想法是可行的。
Siliarus,jwells131313 -也许你有什么进一步的建议?
发布于 2016-11-15 16:41:58
好的,从Weld/CDI的观点来看,这里是如何禁用注入到这些字段中的。请注意,我不了解HK2,所以我不知道如何将它链接到那里,但从CDI的角度来看,您需要将bean作为@Dependent (以避免在事情会变得更糟糕的地方使用代理)。您还没有指定CDI的版本,所以我将为这两个版本做注释: 1.x和2.0。
实际上我遇到了两件事,首先是ProcessAnnotatedType阶段,在这个阶段,你可以删除@Inject注解,这样当CDI接受这个带注解的类型(它变成了bean)时,它不会再把它看作注入点。您可以按如下方式执行此操作:
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。这种方法的优点在于,您可以直接在此处挂接HK2内部。其主要思想是覆盖javax.enterprise.inject.spi.InjectionTarget.inject(T, CreationalContext<T>)并将HK2代码放在此处,因此当CDI实际尝试进行注入时,它将使用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,涵盖了所有这些内容,因此可以作为一个示例来了解如何实现这样的包装器。
https://stackoverflow.com/questions/40592677
复制相似问题