2016-11-14 8 views
1

갖는 클래스과 같이 @Inject를 생략 :CDI 용접은

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

가 C에 주입하지 용접을 말할 수 있습니까?

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

하지만 다음 B 개체도 삽입되지 않을 수 있습니다. 나는 sth를 찾고 있는데 : "클래스 이름이 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로 설정했습니다.

섬세한 부정확는 라인 : 나는 B 형에 대한 생산이 B.에

wrappedInjectionTarget.inject(instance, ctx); 

수행 및 CDI 주입하지만 난이 특정 클래스에 내 자신에 그것을 만들 - 프로듀서를 사용하지. 객체 B는 처리해야하며 manageBViaReflection을 사용하여 값을 재정의 할 때 먼저 처리해야합니다. 약간 지저분하지만 일반적으로 그 아이디어가 효과가 있습니다.

Siliarus, jwells131313 - 더 많은 제안이 있으십니까?

+0

누가 클래스 A, 용접 (CDI) 또는 HK2를 작성합니까? A의 생성자에 스택 추적을 인쇄하거나 중단 점을 넣을 수 있다는 것을 모른다면 – jwells131313

+0

A가 CDI에 의해 생성됩니다. – maciek

+0

@maciek 지금 어떤 문제인지 잘 모르겠습니다. 첫째, 왜'manageBViaReflection'이 필요한가요? 둘째, '나는 B 형을 생산한다'- 왜? CDI를 생산하지 않으려 고하지 마라. 너 스스로해라. 그렇지? 당신을 혼란스럽게하는 CDI 계층 구조 ('InjectionTarget extends Producer')가주의 깊다면,이 경우'Producer '은 고전적인'@ Produces'가 아닙니다. [javadoc] (https://github.com/cdi- spec/cdi/blob/1.2/api/src/main/java/javax/enterprise/inject/spi/Producer.java # L38) – Siliarus

답변

1

좋아요, Weld/CDI 관점에서,이 필드에 주입을 비활성화하는 방법은 다음과 같습니다. HK2에 대해서는 잘 모르기 때문에 CDI 관점에서 빈을 @Dependent (필요없는 곳에서 프록시가 발생하지 않도록)해야합니다. CDI의 버전을 지정하지 않았으므로 1.x 및 2.0 모두에 대해 메모를 작성합니다. 저 두 가지가 처음이다에

은 실제로 무슨 일이 온다, 당신은 @Inject 주석을 제거 할 수 그것 ProcessAnnotatedType 상, CDI, 그것은 더 이상 것입니다 (이 콩으로 변합니다) 유형을 주석 것을 취한다 때 있도록 주사 점으로 보아라. 둘째

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의 좋은 거대한 세트가 마음에 곰 같은 래퍼를 구현하는 방법을 볼 수 예제로 사용할 수 있습니다.