기본적으로 그렇게하려면 portable CDI extension이라고해야합니다.
그러나 길기 때문에 약간의 조정이 필요하므로 더 자세히 설명하겠습니다. 용접 문서가 설명처럼
휴대용 확장
은, 첫 번째 단계는 하나의 흥미로운 CDI 이벤트에 해당하는 코드를 작성하는 것입니다있는 Extension
태그 인터페이스를 구현하는 클래스를 만드는 것입니다. 그 정확한 경우, 가장 흥미로운 사건은 내 마음에, AfterBeanDiscovery입니다. 실제로이 이벤트는 CDI impl에 의해 모든 "local"bean이 발견 된 후에 발생합니다.
그래서, 확장을 작성하는 것은 더 적은 OPR이며, 해당 이벤트에 대한 처리기를 작성 :
public void loadJndiBeansFromServer(
@Observes AfterBeanDiscovery beanDiscovery, BeanManager beanManager)
throws NamingException, ClassNotFoundException, IOException {
// Due to my inability to navigate in server JNDI naming (a weird issue in Glassfish naming)
// This props maps interface class to JNDI name for its server-side
Properties interfacesToNames = extractInterfacesToNames();
// JNDI properties
Properties jndiProperties = new Properties();
Context context = new InitialContext();
for (Entry<?, ?> entry : interfacesToNames.entrySet()) {
String interfaceName = entry.getKey().toString();
Class<?> interfaceClass = Class.forName(interfaceName);
String jndiName = entry.getValue().toString();
Bean<?> jndiBean = createJndIBeanFor(beanManager, interfaceClass, jndiName, jndiProperties);
beanDiscovery.addBean(jndiBean);
}
}
빈을 만들기 사소한 작동되지 않습니다 : 더 고급 용접에 "기본"자바 반사 객체를 전달해야합니다 것들 (글쎄, 내 경우에는)
private <Type> Bean<Type> createJndIBeanFor(BeanManager beanManager, Class<Type> interfaceClass,
String jndiName, Properties p) {
AnnotatedType<Type> annotatedType = beanManager
.createAnnotatedType(interfaceClass);
// Creating injection target in a classical way will fail, as interfaceClass is the interface of an EJB
JndiBean<Type> beanToAdd = new JndiBean<Type>(interfaceClass, jndiName, p);
return beanToAdd;
}
마지막으로 JndiBean 클래스를 작성해야합니다. 그러나 전에는 주석 영역에서 약간의 이동이 필요합니다.
이 사용 된 주석 처음에는
정의, 나는 @EJB
하나를 데 사용합니다. A 불량 아이디어 : Weld는 bean의 해시 코드를 빌드하기 위해 qualifier annotation 메소드를 사용하여 결과를 호출합니다! 그래서, 나는 자신의 @JndiClient
어노테이션을 만들었는데, 어노테이션은 아무런 방법도없고, 상수도 아니기 때문에 가능한 한 간단 해졌습니다.
두 개념이 여기에 병합 JNDI를 클라이언트 빈을 구축.
나는 두 개의 인터페이스 구현이 종종 자신의 상태 중 일부를 공유한다는 것을 알 수 있었다. 그래서 나는 독특한 클래스를 사용하여 impelment하기로 결정했습니다 다음 JndiBean
를! 그 콩에서
, 방법의 대부분은 (또는 기본값) 비어 이러한 인터페이스의 메서드로합니다 (EJB 원격 인터페이스와 모든 확장
@Remote
인터페이스를 반환해야합니다
Bean#getTypes
을 제외하는 수 AnnotationLiteral
가 @JndiClient
인터페이스에 대응 : 하나의 원소를 포함하는 집합을 반환
Bean#getQualifiers
)이 인터페이스를 통해 호출 될 수있다.
Contextual#create
(당신은 콩의 콘텐츠를 확장하지 않았다 잊으 셨나요?) 조회 수행하는 :
@Override
public T create(CreationalContext<T> arg0) {
// Some classloading confusion occurs here in my case, but I guess they're of no interest to you
try {
Hashtable contextProps = new Hashtable();
contextProps.putAll(jndiProperties);
Context context = new InitialContext(contextProps);
Object serverSide = context.lookup(jndiName);
return interfaceClass.cast(serverSide);
} catch (NamingException e) {
// An unchecked exception to go through weld and break the world appart
throw new LookupFailed(e);
}
}
을 그리고 그 모든
사용입니까? 이러한 문제
미래가없는
private @Inject @JndiClient MyRemoteEJB instance;
그리고 작동으로
글쎄, 지금 내 글래스 피쉬 자바 클라이언트 코드에, 내가 쓸 수있는 일?
음, 지금은 사용자 자격 증명이 관리되지 않지만 나는 C CDI : Contexts ...를 사용하면 완전히 가능할 것이라고 생각합니다. 오! 컨텍스트 : scopes!