2012-09-04 2 views
4

CDI conversation 인스턴스는 프로그래밍 방식으로 현재 thread이 원하는 대화와 연결된 CDI request을 처리하는 데 사용되는 인스턴스라는 것을 알기 만하면됩니까? 그리고 가능하다면 어떻게? 특히프로그래밍 방식 대화 조회

는, 제가하고 싶은 것은 이것이다 :

@ConversationScoped 
public class UnitOfWork {...} 

public class Client { 
    @Inject transient UnitOfWork uof; 
... 
} 

public class Room { 
    @Inject transient UnitOfWork uof; 
... 
} 

하지만 uof 인스턴스 변수를 초기화하는 프로그램상에서 메커니즘을 사용하는 대신 ClientRoom 엔티티는 그들이 아무튼 때문에합니다 (@Inject 주석을 적용 t 주사 지원).

public static <B> B getManagedBean(Class<B> type, Annotation... qualifiers) { 
    try { 
     BeanManager beanManager = InitialContext.doLookup("java:comp/BeanManager"); 
     Set<Bean<?>> beans = beanManager.getBeans(type, qualifiers); 
     Bean<B> bean = (Bean<B>) beanManager.resolve(beans); 
     CreationalContext<B> cc = beanManager.createCreationalContext(bean); 
     return bean.create(cc); 
    } catch (NamingException e) { 
     throw new RuntimeException("", e); 
    } 
} 

하지만 문제는 위의 방법을 이용하여 주어진 콩은 새가 있다는 것입니다은 (호출 할 때마다 새로운를 제공합니다
은 이미 다음과 같은 정적 인 방법에 의해 얻어진 BeanManager에 의해 UnitOfWork를 주입 tryed 예를 들어, ClientRoom이 동일한 대화 범위 범위 인스턴스 인 UnitOfWork을 공유해야합니다.

답변

1

답변이 매우 가까웠지만 간과했습니다. 예, BeanManager를 사용하여 현재 컨텍스트 (현재 스레드와 연관된 컨텍스트)에 포함 된 모든 Bean의 Bean 클래스 인스턴스를 얻을 수 있습니다.

public static <B> B getContextualBeanInstance(Class<B> type, Annotation... qualifiers) { 
    try { 
     BeanManager beanManager = InitialContext.doLookup("java:comp/BeanManager"); 
     Set<Bean<?>> beans = beanManager.getBeans(type, qualifiers); 
     Bean<?> bean = beanManager.resolve(beans); 
     CreationalContext<?> cc = beanManager.createCreationalContext(bean); 
     return (B) beanManager.getReference(bean, type, cc); 
    } catch (NamingException e) { 
     throw new RuntimeException("", e); 
    } 
} 

내가 질문 게시물에 언급 된 방법의 유일한 차이점이 하나가 BeanManager#getReference(..) 대신 Bean#create(..) 사용한다는 것입니다 : 이 방법은 작업을 수행합니다.

매개 변수화 된 bean 유형을 지원하려면 Class<B>에서 Type으로 type 매개 변수의 유형을 변경하십시오.

빈이 @Dependent scoped 인 경우 메모리 누수를 피하기 위해 Bean 클래스 인스턴스가 파기되어야합니다. Here 잘하는 방법을 설명합니다.

2

죄송 아닌 진짜 대답,하지만 너무 많은 코멘트에 쓰고 :

기관은 의존성 주입를 지원하지 않는 이유가 있습니다

- 자신의 라이프 사이클을 관리 빈의 라이프 사이클에서 분리되어 주로 때문이.

엔티티의 DI에 대한 사용 사례가 실제로 표시되지만이 접근법의 이점이 위험을 능가하는지 확인하기 위해 두 배 (세 배) 확인합니다. 일종의 2 차 수준 캐시 지옥에서 퍼시스턴스 컨텍스트를 해킹하는 경우가 있습니다.)

+0

주입 된 모든 속성이 일시적 일 때 적용되는 위험은 있습니까? – Readren

+0

그것은 단지 하나의 패싯입니다. 엔티티의 생성/캐싱/직렬화에 대한 제어력이나 영향력이별로 없다는 점에서 가장 큰 문제가 있습니다. 유스 케이스는 괜찮은 편이지만, 틀린 것은 아닙니다. 확실히 혼란 스럽습니다. –

+0

'@ Entity' 클래스의 인스턴스는 여전히 javax.persistence.Query 인스턴스 등을 통해 지속성 유닛에 의해 표준 방식으로 생성됩니다. 내 approuch의 차이점은 단순 POJO가 아니라 행동을 가진 객체라는 점입니다. 그리고 주입 된 속성은 모두 일시적이며 서비스 위치 지정자의 도움으로 게으르게 초기화됩니다. 해결해야 할 문제는 서비스 검색 자 내부입니다.현재'Thread'의 소유자 인 요청과 관련된'Conversation'의 인스턴스를 얻을 수 있어야합니다. – Readren