【问题标题】:CDI Weld omit @InjectCDI Weld 省略 @Inject
【发布时间】: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&lt;T&gt; 不是经典的@Produces,请参阅其javadoc 了解更多信息。
  • 好吧,忘记 B 的制作人——我确实想自己制作。那么如何将字段 B b 设置为 A 类中自定义生成的对象(我想将其设置在那里,对吗?)据我所知,当 B b 引用上方存在 @Inject 注释时会调用 public void inject(T instance, CreationalContext&lt;T&gt; ctx) ?这意味着如果存在@Inject,那么 Weld 会检查它是否能够在部署阶段执行注入。如果我没有 @Inject B b 则不会调用 inject(T instance, CreationalContext&lt;T&gt; ctx) 并且我无法生成和设置我自己的对象。
  • 您能否提供遵循您的想法的方法public void inject(T instance, CreationalContext&lt;T&gt; ctx) 的示例伪代码实现?让我们假设对象 B 在 inject(...) 的开头已经以某种方式创建了。我应该如何在这个 inject(...) 方法中将对象 B 注入到 T 实例中?也许我错过了一些明显的功能?

标签: java dependency-injection cdi weld hk2


【解决方案1】:

好的,从 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&lt;T&gt;)并将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 集合,涵盖了所有这些内容,因此可以用作示例来了解如何实现此类包装器。

【讨论】:

    猜你喜欢
    • 2014-03-21
    • 2014-07-15
    • 2016-02-14
    • 2013-08-09
    • 2017-11-08
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多