예, CDI와 EJB를 자유롭게 혼합하여 훌륭한 결과를 얻을 수 있습니다. @WebService
및 을 사용하는 것처럼 들리는데 @Schedule
, 이는 EJB를 믹스에 추가하는 좋은 이유입니다.
많은 혼란이 있기 때문에 EJB와 CDI가 서로 관련되는 일반적인 정보가 있습니다.
EJB> = CDI
EJB 는 CDI 빈이므로 CDI의 모든 이점이 있습니다. 그 반대는 사실이 아닙니다 (아직). 따라서 "EJB vs CDI"라는 논리가 실제로 "EJB + CDI vs CDI"로 해석되는 것처럼 생각하는 습관을 들이지 마십시오. 이것은 이상한 방정식입니다.
향후 Java EE 버전에서는 계속해서 정렬 할 것입니다. 정렬이란 사람들 이 상단에 @Stateful
, @Stateless
또는 @Singleton
주석 없이 이미 할 수있는 작업을 수행 할 수 있도록하는 것 입니다.
구현 용어의 EJB 및 CDI
궁극적으로 EJB와 CDI는 프록시 구성 요소라는 동일한 기본 설계를 공유합니다. EJB 또는 CDI 빈에 대한 참조를 얻을 때 실제 빈이 아닙니다. 오히려 당신에게 주어진 물건은 가짜 (프록시)입니다. 이 가짜 개체에서 메서드를 호출하면 호출은 인터셉터, 데코레이터 등을 통해 호출을 전송하고 트랜잭션 또는 보안 검사를 처리 할 컨테이너로 이동합니다. 모든 작업이 완료되면 마침내 호출이 실제 객체로 이동하고 결과는 프록시를 통해 호출자에게 다시 전달됩니다.
차이점은 호출 할 개체를 확인하는 방법에만 있습니다. "해결됨"이란 단순히 컨테이너가 호출 할 실제 인스턴스를 찾는 위치와 방법을 의미합니다.
CDI에서 컨테이너는 기본적으로 특정 기간 (요청 별 @RequestScoped
, HTTP 세션 별 @SessionScoped
, 애플리케이션 별 @ApplicationScoped
, JSF 대화 @ConversationScoped
별 또는 사용자 지정 범위 구현 별) 동안 유지되는 해시 맵 인 "범위"를 찾습니다 .
EJB에서 컨테이너는 Bean이 유형 인 경우 해시 맵을 찾습니다 @Stateful
. @Stateful
빈은 또한 살고 범위에있는 다른 모든 콩 죽는 원인이 위 범위 주석을 사용할 수 있습니다. EJB @Stateful
에서 본질적으로 "모든 범위"빈입니다. 은 @Stateless
기본적으로 인스턴스 풀 - 당신은 하나의 호출의 기간 동안 풀에서 인스턴스를 얻을. 는 @Singleton
본질적으로@ApplicationScoped
따라서 기본 수준에서 "EJB"빈으로 할 수있는 모든 작업은 "CDI"빈으로 할 수 있어야합니다. 내부적으로는 구분하기가 매우 어렵습니다. 인스턴스가 해결되는 방법을 제외하고 모든 배관은 동일합니다.
이 프록시를 수행 할 때 컨테이너가 제공 할 서비스 측면에서 현재 동일하지는 않지만 Java EE 사양 수준에서 작업하고 있습니다.
성능 참고
당신이 가지고있는 "가벼운"또는 "무거운"정신적 이미지는 무시하십시오. 그게 모두 마케팅입니다. 대부분의 경우 내부 디자인이 동일합니다. CDI 인스턴스 확인은 약간 더 동적이고 상황에 맞기 때문에 약간 더 복잡 할 수 있습니다. EJB 인스턴스 분석은 비교해 보면 상당히 정적이고 멍청하고 단순합니다.
TomEE의 구현 관점에서 말할 수 있습니다. EJB를 호출하는 것과 CDI를 호출하는 것 사이에는 성능 차이가 거의 없습니다.
기본값은 POJO, CDI, EJB 순입니다.
물론 혜택이 없을 때는 CDI 나 EJB를 사용하지 마십시오. 주입, 이벤트, 인터셉터, 데코레이터, 라이프 사이클 추적 등을 원할 때 CDI를 사용하십시오. 그게 대부분의 시간입니다.
그 기본을 넘어, 유용한 컨테이너 서비스의 수는 당신이 당신의 CDI의도 빈 추가하여 EJB 할 경우에만 사용 할 수있는 옵션이있다 @Stateful
, @Stateless
또는 @Singleton
거기에있다.
다음은 EJB를 나눈 짧은 목록입니다.
JAX-WS 사용
JAX-WS 노출 @WebService
. 내가 게으른. (가) 때 @WebService
또한 EJB, 당신은 그것을 나열하고있는 서블릿으로 매핑 할 필요가 없습니다 web.xml
파일. 그것은 나에게 일입니다. 또한 아래에 언급 된 다른 기능을 사용할 수있는 옵션도 제공됩니다. 그래서 그것은 나에게 쉬운 일입니다.
에 사용 가능 @Stateless
하고 @Singleton
단지.
JAX-RS 사용
비아 JAX-RS 자원을 노출 @Path
. 나는 여전히 게으르다. RESTful 서비스가 EJB이기도 한 경우 다시 자동 검색이 가능하며이를 JAX-RS Application
서브 클래스 또는 이와 유사한 것에 추가 할 필요가 없습니다 . 또한 @WebService
아래에 언급 된 훌륭한 기능을 원하거나 사용 하는 경우 와 똑같은 빈을 노출 할 수 있습니다.
에 사용 가능 @Stateless
하고 @Singleton
단지.
시작 논리
를 통해 시작시로드합니다 @Startup
. 현재 CDI에는 이에 상응하는 것이 없습니다. 어떻게 든 우리 AfterStartup
는 컨테이너 수명주기에 이벤트 와 같은 것을 추가하지 못했습니다 . 우리가 이것을했다면, 당신은 단순히 @ApplicationScoped
그것을 청취 하는 빈을 가질 수 있었고 그것은 효과적으로 @Singleton
with와 동일 할 것 입니다 @Startup
. CDI 1.1 목록에 있습니다.
에 사용 가능한 @Singleton
전용.
병렬로 작업
@Asynchronous
메소드 호출. 스레드 시작은 서버 측 환경에서 절대 안됩니다. 스레드가 너무 많으면 성능이 크게 저하됩니다. 이 주석을 사용하면 컨테이너의 스레드 풀을 사용하여 수행하는 작업을 병렬화 할 수 있습니다. 굉장합니다.
에 사용할 수 @Stateful
, @Stateless
과 @Singleton
.
작업 예약
@Schedule
또는 ScheduleExpression
기본적으로 cron 또는 Quartz
기능입니다. 또한 매우 굉장합니다. 대부분의 컨테이너는이를 위해 덮개 아래에 Quartz를 사용합니다. 그러나 대부분의 사람들은 Java EE에서의 스케줄링 작업이 트랜잭션이라는 것을 모릅니다! 데이터베이스를 업데이트 한 다음 일부 작업을 예약하고 그중 하나가 실패하면 둘 다 자동으로 정리됩니다. 경우 EntityManager
계속 호출이 실패하거나 문제의 홍조가, 작업 취소 일정 필요가 없습니다. 예, 거래.
에 사용 가능 @Stateless
하고 @Singleton
단지.
JTA 트랜잭션에서 EntityManagers 사용
물론 트랜잭션에 대한 위의 참고는 JTA
관리되는 EntityManager
. 일반 "CDI"와 함께 사용할 수 있지만 컨테이너 관리 트랜잭션이 없으면 UserTransaction
커밋 / 롤백 논리를 매우 단조롭게 복제 할 수 있습니다 .
CDI, JSF를 포함한 모든 Java EE 구성 요소에 사용 가능 @ManagedBean
, @WebServlet
, @WebListener
, @WebFilter
, 등 @TransactionAttribute
주석 단에 볼 수 있습니다 @Stateful
, @Stateless
그리고 @Singleton
단지.
JTA 관리 유지 EntityManager
EXTENDED
관리는 EntityManager
당신이 유지할 수 EntityManager
사이의 공개 JTA
거래 및하지 잃게 캐시 된 데이터를. 적절한 시간과 장소에 적합한 기능입니다. 책임감있게 사용하십시오 :)
에 사용 가능한 @Stateful
전용.
쉬운 동기화
동기화가 필요할 때 @Lock(READ)
및 @Lock(WRITE)
주석은 매우 훌륭합니다. 동시 접속 관리를 무료로 할 수 있습니다. 모든 ReentrantReadWriteLock 배관을 건너 뜁니다. 동일한 버킷에는이며 @AccessTimeout
, 포기하기 전에 스레드가 Bean 인스턴스에 액세스하기 위해 대기해야하는 시간을 말할 수 있습니다.
@Singleton
콩에만 사용할 수 있습니다.