首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CDI Weld省略@Inject

CDI Weld省略@Inject
EN

Stack Overflow用户
提问于 2016-11-14 23:48:16
回答 1查看 399关注 0票数 2

拥有这样的类:

代码语言:javascript
复制
public class A {
   @Inject B b;
   @Inject C c;
}

有没有可能告诉Weld不要注入到c中?我可以使用event来否决一个类:

代码语言:javascript
复制
<T> void processAnnotatedType(@Observes  ProcessAnnotatedType<T> pat) 

但是B对象也不会被注入。我正在搜索类似这样的东西:“如果类名是A,字段类型是C,那么就省略注入。”

更具体地说,我希望HK2引擎注入"C“字段,但问题是HK2和Weld都使用了@Inject注解。

Siliarus解决方案:

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

代码语言:javascript
复制
<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中

代码语言:javascript
复制
public CustomInjection(InjectionTarget<T> originalInjectionTarget, BeanManager beanManager) {
    this.wrappedInjectionTarget = originalInjectionTarget;
    this.beanManager = beanManager;
}

像这样:

代码语言:javascript
复制
@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。

微妙的不准确之处在于这一行:

代码语言:javascript
复制
wrappedInjectionTarget.inject(instance, ctx);

在B上执行和CDI注入。我将producer设置为类型B,但我想在这个特定的类中自己创建它--而不是使用producer。对象B必须被释放,当我使用manageBViaReflection覆盖它的值时,我必须首先释放它-这有点混乱,但通常这个想法是可行的。

Siliarus,jwells131313 -也许你有什么进一步的建议?

EN

回答 1

Stack Overflow用户

发布于 2016-11-15 16:41:58

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

实际上我遇到了两件事,首先是ProcessAnnotatedType阶段,在这个阶段,你可以删除@Inject注解,这样当CDI接受这个带注解的类型(它变成了bean)时,它不会再把它看作注入点。您可以按如下方式执行此操作:

代码语言:javascript
复制
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。

代码语言:javascript
复制
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,涵盖了所有这些内容,因此可以作为一个示例来了解如何实现这样的包装器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40592677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档