먼저 몇 가지 설명을하겠습니다.
관리 빈 정의 : 일반적으로 관리 빈은 컨테이너에 의해 수명주기 (구성, 파괴 등)가 관리되는 객체입니다.
Java ee에는 JSF 컨테이너, EJB 컨테이너, CDI 컨테이너, Servlet 컨테이너 등과 같이 객체의 수명주기를 관리하는 많은 컨테이너가 있습니다.
이러한 모든 컨테이너는 독립적으로 작동하며, 애플리케이션 서버 초기화에서 부팅하고 배포 시간에 jar, ejb-jar, war 및 ear 파일을 포함한 모든 아티팩트의 클래스를 스캔하고 이에 대한 일부 메타 데이터를 수집하고 저장 한 다음 객체가 필요할 때 런타임에 클래스의 인스턴스를 제공하고 작업을 마친 후에는 해당 클래스의 인스턴스를 파괴합니다.
따라서 우리는 다음과 같이 말할 수 있습니다.
- JSF 관리 빈
- CDI 관리 Bean
- EJB 관리 Bean
- 그리고 서블릿조차도 서블릿 컨테이너 인 컨테이너에 의해 인스턴스화되고 파괴되기 때문에 관리 빈입니다.
따라서 Managed Bean 단어를 볼 때 문맥이나 유형 (JSF, CDI, EJB 등)에 대해 질문해야합니다.
그런 다음 이러한 컨테이너가 많은 이유를 물어볼 수 있습니다. AFAIK, Java EE 직원들은 종속성 주입 프레임 워크를 원했지만 미래의 요구 사항을 예측할 수 없었고 EJB 1.0을 만든 다음 하나의 사양에 모든 요구 사항을 수집 할 수 없었습니다. 2.0, 3.0, 이제 3.1이지만 EJB의 목표는 일부 요구 사항 (트랜잭션, 분산 구성 요소 모델 등)에 대한 것입니다.
동시에 (병렬로) 그들은 JSF도 지원해야한다는 것을 깨달았고, JSF 관리 빈과 JSF 빈을위한 또 다른 컨테이너를 만들고 그것을 성숙한 DI 컨테이너로 간주했지만 여전히 완전하고 성숙한 컨테이너는 아닙니다.
그 후 Gavin King과 다른 멋진 사람들;) 내가 본 것 중 가장 성숙한 DI 컨테이너 인 CDI를 만들었습니다. CDI (Seam2, Guice 및 Spring에서 영감을 얻음)는 JSF와 EJB, 그리고 pojo 주입, 생산자 방법, 인터셉터, 데코레이터, 통합 SPI, 매우 유연함 등과 같은 많은 다른 유용한 요소 사이의 격차를 채우기 위해 만들어졌습니다. EJB 및 JSF 관리 빈이 수행하는 작업은 성숙하고 강력한 DI 컨테이너 하나만 가질 수 있습니다. 그러나 이전 버전과의 호환성과 정치적 이유 때문에 Java EE 사용자는이를 유지하려고합니다 !!!
여기에서 이러한 각 유형의 차이점과 사용 사례를 찾을 수 있습니다.
JSF 관리 빈, CDI 빈 및 EJB
JSF는 처음에 주석 기반 빈을 포함하도록 JSF 2.0에 대해 개선 된 자체 관리 빈 및 종속성 주입 메커니즘으로 개발되었습니다. CDI가 Java EE 6과 함께 출시되었을 때 해당 플랫폼을위한 관리 빈 프레임 워크로 간주되었으며 물론 EJB는 10 년이 훨씬 넘도록 모두 구식이었습니다.
물론 문제는 어느 것을 사용할 것인지 언제 사용할 것인지 아는 것입니다.
가장 간단한 JSF 관리 빈부터 시작하겠습니다.
JSF 관리 빈
간단히 말해서 Java EE 6 용으로 개발하고 CDI를 사용하는 경우에는 사용하지 마십시오. 의존성 주입을위한 간단한 메커니즘을 제공하고 웹 페이지에 대한 백킹 빈을 정의하지만 CDI 빈보다 훨씬 덜 강력합니다.
@javax.faces.bean.ManagedBean
선택적 이름 매개 변수를 사용하는 주석을 사용하여 정의 할 수 있습니다 . 이 이름은 JSF 페이지에서 Bean을 참조하는 데 사용할 수 있습니다.
범위는 javax.faces.bean
요청, 세션, 애플리케이션,보기 및 사용자 정의 범위를 포함하는 패키지에 정의 된 다른 범위 중 하나를 사용하여 Bean에 적용 할 수 있습니다 .
@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
....
....
}
JSF 빈은 어떤 종류의 수동 코딩 없이는 다른 종류의 빈과 혼합 될 수 없습니다.
CDI 빈
CDI는 Java EE 6의 일부로 출시 된 빈 관리 및 종속성 주입 프레임 워크이며 완전하고 포괄적 인 관리 빈 기능을 포함합니다. CDI 빈은 단순한 JSF 관리 빈보다 훨씬 더 진보되고 유연합니다. 인터셉터, 대화 범위, 이벤트, 유형 안전 주입, 데코레이터, 고정 관념 및 생산자 방법을 사용할 수 있습니다.
CDI Bean을 배치하려면 클래스 경로의 META-INF 폴더에 beans.xml이라는 파일을 배치해야합니다. 이렇게하면 패키지의 모든 빈이 CDI 빈이됩니다. CDI에는 많은 기능이 있지만 여기서 다루기에는 너무 많지만 JSF와 유사한 기능에 대한 빠른 참조로 javax.enterprise.context
패키지에 정의 된 범위 중 하나 (즉, 요청, 대화)를 사용하여 CDI 빈의 범위를 정의 할 수 있습니다. , 세션 및 애플리케이션 범위). JSF 페이지에서 CDI Bean을 사용하려면 javax.inject.Named
어노테이션을 사용하여 이름을 지정할 수 있습니다 . 빈을 다른 빈에 주입하려면 필드에 javax.inject.Inject
주석 을 추가합니다 .
@Named("someBean")
@RequestScoped
public class SomeBean {
@Inject
private SomeService someService;
}
위에서 정의한 것과 같은 자동 주입은 주입하려는 특정 클래스를 일치시키는 데 도움이되는 한정자를 사용하여 제어 할 수 있습니다. 결제 유형이 여러 개인 경우 비동기인지 여부에 대한 한정자를 추가 할 수 있습니다. @Named
어노테이션을 한정자로 사용할 수 있지만 EL에서 빈을 노출하기 위해 제공되는 것처럼 사용해서는 안됩니다.
CDI는 프록시를 사용하여 범위가 일치하지 않는 빈 주입을 처리합니다. 이 때문에 요청 범위 Bean을 세션 범위 Bean에 삽입 할 수 있으며 각 요청에 대해 프록시가 요청 범위 Bean의 라이브 인스턴스에 다시 연결되기 때문에 참조는 각 요청에서 여전히 유효합니다.
CDI는 인터셉터, 이벤트, 새로운 대화 범위 및 기타 많은 기능을 지원하므로 JSF 관리 Bean보다 훨씬 더 나은 선택이 될 수 있습니다.
EJB
EJB는 CDI 빈보다 이전이며 어떤면에서는 CDI 빈과 비슷하고 다른면에서는 매우 다릅니다. 주로 CDI 빈과 EJB의 차이점은 EJB가 다음과 같다는 것입니다.
- 거래
- 원격 또는 로컬
- 리소스를 확보하는 Stateful Bean을 비활성화 할 수 있습니다.
- 타이머 사용 가능
- 비동기적일 수 있음
두 가지 유형의 EJB를 상태 비 저장 및 상태 저장이라고합니다. Stateless EJB는 두 웹 요청간에 상태를 유지하지 않는 스레드로부터 안전한 일회용 Bean으로 생각할 수 있습니다. Stateful EJB는 상태를 유지하며 폐기 될 때까지 필요한 기간 동안 생성 및 유지 될 수 있습니다.
EJB를 정의하는 것은 간단합니다. javax.ejb.Stateless
또는 javax.ejb.Stateful
주석을 클래스에 추가하기 만하면 됩니다.
@Stateless
public class BookingService {
public String makeReservation(Item Item, Customer customer) {
...
...
}
}
Stateless Bean은 종속 범위를 가져야하며 Stateful 세션 Bean은 모든 범위를 가질 수 있습니다. 기본적으로 트랜잭션이지만 트랜잭션 속성 주석을 사용할 수 있습니다.
EJB와 CDI 빈은 기능면에서 매우 다르지만이를 통합하는 코드를 작성하는 것은 CDI 빈을 EJB에 주입 할 수 있고 EJB를 CDI 빈에 주입 할 수 있기 때문에 매우 유사합니다. 하나를 다른 하나에 주입 할 때 구별 할 필요가 없습니다. 다시 말하지만, 다른 범위는 프록 싱을 사용하여 CDI에서 처리됩니다. 이에 대한 한 가지 예외는 CDI가 원격 EJB의 주입을 지원하지 않지만이를위한 간단한 생산자 메소드를 작성하여 구현할 수 있다는 것입니다.
javax.inject.Named
뿐만 아니라 예선은 EJB에서 사용할 수있는 주석이 삽입 지점에 일치합니다.
어떤 콩을 사용하는 경우
언제 어떤 빈을 사용해야하는지 어떻게 알 수 있습니까? 단순한.
서블릿 컨테이너에서 작업하지 않고 Tomcat에서 CDI를 작동시키고 싶지 않은 경우가 아니면 JSF 관리 Bean을 사용하지 마십시오 (일부 Maven 아키 타입이 있으므로 변명의 여지가 없습니다).
일반적으로 트랜잭션 기능과 같은 EJB에서 사용할 수있는 고급 기능이 필요하지 않으면 CDI 빈을 사용해야합니다. 자체 인터셉터를 작성하여 CDI 빈을 트랜잭션으로 만들 수 있지만 지금은 CDI가 모퉁이에있는 트랜잭션 CDI 빈을 얻을 때까지 EJB를 사용하는 것이 더 간단합니다. 서블릿 컨테이너에 갇혀 있고 CDI를 사용하는 경우 손으로 쓴 트랜잭션이나 자체 트랜잭션 인터셉터가 EJB가없는 유일한 옵션입니다.
당신이 사용해야하는 경우 @ViewScoped
CDI에 당신이해야
- 사용 솔기 - 얼굴 또는 에서 MyFaces CODI의 모듈을. 클래스 경로에 그중 하나를 추가
@ViewScoped
하면 CDI에서 작동합니다. MyFaces CODI는 @ViewScoped를 더욱 확고하게 지원합니다.
- 사용에서 MyFaces CODI의는
@ViewAccessScoped
, 그냥, 아파치에 의해 CDI의 상단에 작성된 확장 다운로드 IT 및 사용 @ViewAccessScoped
대신 주석을 @ViewScoped
.
- CDI
@ConversationScoped
를 사용하고 오래 실행하십시오. 자세한 내용은 여기를 참조 하십시오 .
- 사용 Omnifaces @ViewScoped 주석
여기 에서 일부 부분을 훔쳤 습니다 .