Java EE 6 @ javax.annotation.ManagedBean 대 @ javax.inject.Named 대 @ javax.faces.ManagedBean


107

Java EE 6 사양에 약간의 혼란이 있다고 생각합니다. 몇 가지 주석 세트가 있습니다.

우리는이 javax.ejb같은 주석 @Stateful@StatelessEJB를 생성합니다.

@javax.annotation.ManagedBean관리 Bean을 작성하는 것도 있습니다 .

javax.enterprise.context좋아요 @SessionScoped및에 주석이 있습니다 @RequestScoped.

더 많은 것은 패키지에 @ManagedBean@SessionScoped/ @RequestScoped주석 이 있습니다 javax.faces.bean.

이벤트를 더 복잡하게 만들기 위해 주석 이있는 패키지 javax.inject@Named있습니다.

누군가가 서로 어떻게 관련되어 있는지 설명해 주시겠습니까?

어디에서 사용할 수 있습니다 @EJB, @Inject또는 @ManagedPropery다른 콩을 주입?


답변:


194

먼저 몇 가지 설명을하겠습니다.

관리 빈 정의 : 일반적으로 관리 빈은 컨테이너에 의해 수명주기 (구성, 파괴 등)가 관리되는 객체입니다.

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가없는 유일한 옵션입니다.

당신이 사용해야하는 경우 @ViewScopedCDI에 당신이해야

  • 사용 솔기 - 얼굴 또는 에서 MyFaces CODI의 모듈을. 클래스 경로에 그중 하나를 추가 @ViewScoped하면 CDI에서 작동합니다. MyFaces CODI는 @ViewScoped를 더욱 확고하게 지원합니다.
  • 사용에서 MyFaces CODI의는 @ViewAccessScoped, 그냥, 아파치에 의해 CDI의 상단에 작성된 확장 다운로드 IT 및 사용 @ViewAccessScoped대신 주석을 @ViewScoped.
  • CDI @ConversationScoped를 사용하고 오래 실행하십시오. 자세한 내용은 여기를 참조 하십시오 .
  • 사용 Omnifaces @ViewScoped 주석

여기 에서 일부 부분을 훔쳤 습니다 .


3
대단합니다! 감사! 완료하려면 JSF 빈에 CDI 또는 EJB 빈을 주입하는 방법을 알려주십시오. 은 @ManagedProperty("#{someBean})"적절한 방법은?
Piotr Gwiazda

2
아니! 작동하지 않습니다. CDI는 사용하여 주석으로 관리 Bean에 당신의 JSF 관리 빈을 설정 @Named@javax.enterprise.context.RequestScoped사용의 CDI 주입 @Inject 어노테이션을 사용하여. 필요하지 않은 경우 jsf 관리 빈을 사용하지 마십시오;).
Mehdi

3
> JEE 사람들은 그들을 지키고 싶다 !!! -그것보다 조금 더 미묘합니다. CDI는 Java EE 6주기에서 다소 늦게 완료되었으며 JSF 2 및 JAX-RS는 이미 완료되었습니다. 그들은 resp를 강화했습니다. 이미 자체 관리 Bean 기능을 도입했습니다. CDI를 조금 더 일찍 사용할 수 있었다면 상황이 다르게 보일 수 있습니다. Java EE 7에서 JSF는 CDI를 채택하고 javax.faces.bean은 결국 더 이상 사용되지 않을 것입니다 (하지만 Java EE에서는 더 이상 사용되지 않는 프로세스가 느리고 좋지만 둘 다).
Arjan Tijms

3
다음과 같이 말할 때 : CDI Bean을 배치하려면 클래스 경로의 META-INF 폴더에 beans.xml이라는 파일을 배치해야합니다. 이렇게하면 패키지의 모든 빈이 CDI 빈이됩니다. 모든 빈이 그것이 무엇인지에 추가하여 CDI 빈이된다는 것을 의미합니까? ManagedBean 및 ViewScoped가있는 JSF ManagedBeans가있는 경우 어떻게합니까? 그들은 여전히 ​​JSF Managed Beans입니까?
Koray Tugay 2013 년

3
이 멋진 기사에서 Java EE 7에 대한 업데이트를 수행 할 수있는 사람이 있습니까?
Martijn Burger

7

네, 혼란 스러울 수 있습니다.

일부 ehm 역사적 이유 때문에 JSF와 CDI는 범위에 대해 동일한 주석을 사용하지만 다른 패키지에서 사용합니다.

아마도 javax.faces.beanJSF 사양에서 가져온 것으로 CDI와 관련이 없다고 추측 할 수 있습니다 . 타당한 이유가없는 한 사용하지 마십시오. .NET의 CDI 주석과 절대 혼합하지 마십시오 javax.ejb. 이것은 버그와 미묘한 변칙의 순전히 끝없는 목록을 생성합니다.

일반적으로 우수한 용접 문서 의 처음 몇 페이지 (또는 그 이상)를 훑어 보는 것이 좋습니다 . 이렇게하면 Java EE 6에 대한 추적이 시작됩니다.

여기에 추가 질문을 게시 할 수 있습니다.


실제로 두 가지 질문이 있습니다. 1. 종종 뷰 범위가 매우 유용하다고 생각합니다. 그러면 JSF 주석을 사용해야합니까? 2. @javax.annotation.ManagedBeanCDI가 모든 클래스를 관리 빈으로 취급하므로 쓸모가 없다는 의미입니다. 맞습니까?
Piotr Gwiazda

좀 빠지는. Seam Faces 등을 사용하여 JSF 범위를 CDI에 연결해야합니다. 그리고 예, 관련 jar 파일에 beans.xml이 있으면 @ManagedBeans가 필요하지 않습니다. 아, 그리고 더 궁금한 점이 있으면 댓글 섹션에서 벗어나기 전에 새 스레드를 시작하는 것이 좋습니다.
jan groth

3

에 대한 구체적인 답변이 없기 때문에 @javax.annotation.ManagedBean유사한 질문에 대한 답변 링크가 있습니다. Backing beans (@ManagedBean) 또는 CDI Beans (@Named)? . 사양은 http://download.oracle.com/otndocs/jcp/managed_beans-1.0-fr-eval-oth-JSpec/ 에서 찾을 수 있습니다 . 그래서 그 나에게 보이는 @javax.annotation.ManagedBean의 일반화 될 운명이되었다 @javax.faces.bean.ManagedBean.

내가 모은 것에서 JSF Managed Beans는 CDI Beans (JSF 2.3에서 더 이상 사용되지 않을 수도 있음)를 위해 단계적으로 제거되고 있으므로 @javax.annotation.ManagedBean지금은 더 이상 사용되지 않는 것 같습니다.


@Named앞으로 대체 @ManagedBean될까요?
Thufir

1
나는 CDI의 것으로 예측 다른 자바 EE 전문가들에 의해 여러 문장을 읽은 @Named콩 JSF를 대체 할 @ManagedBeans예에서 stackoverflow.com/questions/4347374/... , BalusC 말한다 "기대는 @ManagedBean과 친구가 자바에 따라 중단 될 것입니다 EE 8. ".
Hein Blöd 2014 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.