EJB 3.1 및 CDI는 어디에 사용합니까?


120

GlassFish 3 및 EJB 3.1을 사용하는 Java EE 기반 제품을 만들고 있습니다.

내 응용 프로그램에는 세션 빈 , 스케줄러가 있으며 웹 서비스를 사용합니다. 최근에 CDI (Contexts and Dependency Injection) 를 지원하는 Apache TomEE 에 대해 알게되었습니다 . GlassFish 컨테이너는 CDI도 지원합니다.

CDI가 아직 제공하지 않는 기능이 필요하지 않은 세션 Bean을 교체 할 수 있습니까? 그렇다면 얻을 수있는 혜택은 무엇입니까?

답변:


408

예, 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그것을 청취 하는 빈을 가질 수 있었고 그것은 효과적으로 @Singletonwith와 동일 할 것 입니다 @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콩에만 사용할 수 있습니다.


32
Good heavens David :) 나는 당신이 그것을 덮었다 고 생각합니다.
LightGuard 2012

7
이 답변에 감사드립니다. 당신은 내 머리의 막힘을 제거하고 많은 점을 연결했습니다.
Thupten 2014

7
이것은 내가 읽은 주제에 대한 최고의 설명입니다. 또한 실제 사용에서 EJB의 거의 모든 중요한 측면을 다룹니다. 훌륭한 일!!
nanoquack 2014

3
매우 이해하기 쉬우 며 Adam은 엄격한 법적 용어로 잘못되지 않았지만 구별은 의문의 여지가 있습니다. 사양에 따르면 EJB 인스턴스는 컨텍스트가 아니지만 나중에 EJB에 대한 참조 (프록시)가 컨텍스트라고 말합니다. Stateful Bean의 수명주기는 참조 (프록시)를 통해 전적으로 제어되므로 CDI 컨테이너가 해당 참조 (프록시)를 제어 할 때 수학은 동일하게 나옵니다. 즉, Stateful EJB는 효과적으로 상황에 맞출 수 있습니다.
David Blevins 2014 년

3
TESLA에서 점심 시간에 이것을 썼습니까?
에디슨

2

ejb 3.1의 기능을 실제로 사용하지 않는다면 답은 간단합니다. 그러나 당신의 질문은 당신이 인식하지 못한 채로 이익을 얻는 ejb 3.1 개념이 있다고 의심한다는 것을 나타냅니다. 한 가지 예는 컨테이너가 사용할 준비가 된 slsb 풀을 유지할 수 있으므로 jms 및 데이터베이스 연결이 요청의 일부로 주입 될 필요가 없다는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.