2009년 10월 30일 금요일 저자 Roger Kitain
이 테크팁에서는 자바 EE 6 플랫폼에 속하는 세 가지 강력한 기술인 JSR 299: 컨텍스트 및 의존성 주입, JSR 330: 자바를 위한 의존성 주입 및 JSR 314: JavaServer Faces 2.0의 교차를 다룹니다.
JSR 299: 컨텍스트 및 의존성 주입(CDI)은 애플리케이션을 훨씬 쉽게 개발할 수 있게 만드는 자바 EE 환경을 위한 서비스 집합을 정의합니다. CDI는 서블릿, 엔터프라이즈 빈 및 JavaBean과 같은 자바 EE 구성요소가 범위가 잘 정의된 애플리케이션의 수명 주기 내에 존재할 수 있게 해주는 아키텍처를 제공합니다. 또한 CDI 서비스를 통해 이벤트를 시작하고 관찰하여 EJB 세션 빈과 JSF(JavaServer Faces) 관리 빈을 포함한 자바 EE 구성요소가 주입되어 느슨하게 결합되는 방식으로 상호 작용할 수 있습니다. 가장 중요한 점은 CDI가 EJB 및 JSF 프로그래밍 모델을 통합하고 단순화한다는 점일 것입니다. CDI를 통해 엔터프라이즈 빈은 JSF 애플리케이션에서 관리 빈으로 작동할 수 있습니다. CDI는 자체적인 서비스를 통해 웹 계층에 트랜잭션 지원을 제공합니다. CDI는 웹 애플리케이션에서 트랜잭션 리소스에 액세스하기 훨씬 쉽게 할 수 있습니다. 예를 들어, CDI 서비스를 이용하면 자바 Persistence API에서 제공하는 지속성으로 데이터베이스에 액세스하는 자바 EE 웹 애플리케이션을 훨씬 쉽게 만들 수 있습니다.
JSR 330: 자바를 위한 의존성 주입에서는 의존성 주입을 위해 사용할 수 있는 표준 주석 집합을 도입합니다. 의존성 주입은 엔터프라이즈 자바 애플리케이션 개발에 많이 사용되는 기술입니다. 불행히도, 주석 기반 의존성 주입에 대한 표준 접근 방식이 없었습니다. 자바를 위한 의존성 주입은 의존성 주입을 위해 표준화되고 확장 가능한 API를 제공함으로써 변화를 꾀합니다. API는 주입 가능한 클래스에서 사용하기 위한 주석 집합으로 구성됩니다.
JavaServer Faces 기술은 자바 EE 애플리케이션용 사용자 인터페이스(UI)의 개발을 단순화하기 위해 설계된 서버 쪽 구성 요소 프레임워크를 제공합니다. 이 기술의 최신 릴리스인 JSR 314: JavaServer Faces 2.0은 주석 지원과 Facelet 및 컴포지트 구성 요소와 같은 새로운 기능 추가를 통해 자바 EE 애플리케이션용 UI 개발을 훨씬 쉽게 해줍니다.
이 테크팁에서는 JSF 2.0 애플리케이션에서 자바용 CDI 및 의존성 주입의 사용에 관해 설명합니다.
애플리케이션 예
자바용 CDI 및 의존성 주입을 사용하는 JSF 2.0 애플리케이션의 몇몇 핵심 부분을 살펴봅시다. 이 팁에서 제공되는 샘플 애플리케이션 패키지에서 애플리케이션의 소스 코드를 찾을 수 있습니다. 애플리케이션 설치 및 실행 방법에 대한 지침은 샘플 코드 실행을 참조하십시오.
그림 1은 애플리케이션의 UI를 나타낸 것입니다. UI에서는 사용자에게 시스템이 임의로 선택한 숫자를 추측해보라는 메시지를 표시합니다. 이 메시지는 다음과 같습니다. min에서 max 사이의 수를 생각하고 있습니다. 여기서, min과 max는 각각 어림짐작으로 허용 가능한 최소값과 최대값을 나타냅니다. UI에는 사용자가 숫자를 입력할 텍스트 필드, 숫자를 전송하기 위한 추측 버튼, 게임을 다시 시작하기 위한 재설정 버튼이 표시됩니다. 사용자가 정확한 수보다 낮은 수를 입력하는 경우 UI는 더 높음(Higher)!이라는 메시지로 응답합니다. 또한 UI는 프롬프트 메시지의 min 값을 추측한 수보다 높은 값으로 변경합니다. 사용자가 입력한 값이 너무 높은 경우 UI는 더 낮음(Lower)!이라는 메시지로 응답하고 프롬프트 메시지의 max 값을 추측한 수보다 낮은 값으로 변경합니다. 시스템은 추측 횟수에 대한 제한을 설정하고, UI는 각각의 부정확한 추측에 대해 사용자에게 추측할 수 있는 기회가 얼마나 남아 있는지 알려주는 메시지를 표시합니다. 사용자가 수를 정확히 추측하거나 추측 횟수 제한에 이를 때 게임이 끝납니다.
그림 1. 수 추측 JSF 2.0 애플리케이션의 UI |
다음은 애플리케이션의 UI에 대한 코드입니다.
JSF로 애플리케이션을 개발하는 경우 UI의 코드가 눈에 익을 것입니다. 사실, 이 페이지의 모든 것이 표준 JSF 2.0 뷰 마크업입니다. 강조 표시한 표현 언어(EL) 표현식에 주의하십시오. 이 표현식들은 game이라는 이름의 상황별 빈 인스턴스를 가리킵니다. 상황별 빈 인스턴스는 괸리 빈이라고도 하고, 그냥 간단히 빈이라고도 합니다.
실제로, 관리 빈의 개념은 CDI를 벗어납니다. 자바 EE 6에 도입된 관리 빈은 JSF 관리 빈, 엔터프라이즈 빈 및 CDI 빈을 포함하여, 자바 EE의 다양한 모든 종류의 빈을 통합하도록 설계되었습니다. 관리 빈은 자바 EE 컨테이너에서 관리 구성요소로 취급하는 자바 클래스입니다. 선택적으로, EJB 구성요소에서 사용하는 것과 같은 네임스페이스에 이름을 지정할 수 있습니다. 관리 빈은 수명 주기 관리 및 리소스 주입에 주로 관련된 소수의 컨테이너 제공 서비스에도 의존할 수 있습니다. JSF, EJB 및 CDI와 같은 다른 자바 EE 기술은 서비스를 추가하여 이런 관리 빈의 기본적인 정의를 바탕으로 구축됩니다. 예를 들어, JSF 관리 빈은 수명 주기 범위를 추가하고, EJB 세션 빈은 트랜잭션 지원과 같은 서비스를 추가하고, CDI 빈은 의존성 주입과 같은 서비스를 추가합니다.
UI에 대한 코드에 강조 표시된 EL 표현식으로 돌아갈 때, EL 표현식은 다음과 같이 다양한 빈 속성 및 메소드에 바인딩합니다.
- 17, 24 및 25행의 EL 표현식은 빈 속성에 바인딩합니다.
- 21행의 EL 표현식은 빈 속성과 빈 유효성 검사 메소드에 바인딩합니다.
- 22 및 23행의 EL 표현식은 빈 작동 메소드에 바인딩합니다.
보시다시피, JSF 2.0에서는 CDI 빈에 바인딩하는 것이 일반적인 JSF 관리 빈에 바인딩하는 것과 전혀 다르지 않습니다.
간단한 상황별 빈의 분석
앞서 언급한 바와 같이, 이벤트를 시작하고 관찰하여 빈을 수명 주기 컨텍스트에 바인딩하고 주입하여 느슨하게 결합되는 방식으로 다른 빈과 상호 작용할 수 있습니다. 그 밖에도, 자바 코드에서 빈을 직접 호출하거나, 예로 든 애플리케이션의 UI에서 보았듯이 EL 표현식에서 호출할 수도 있습니다. 이를 통해 JSF 페이지가 빈에 직접 액세스할 수 있습니다.
애플리케이션에서 사용되는 game 빈을 살펴봅시다. 다음은 이 빈의 소스 코드입니다.
특히 빈에서 강조 표시된 다음 주석을 잘 살펴보십시오.
- 14행의
@Named주석. 이것은 어떤 이름을 빈과 연관시키기 위해 사용되는 자바용 의존성 주입 주석입니다. 주석에 인수로 지정된 이름이 없기 때문에, 빈의 이름은 첫 번째 문자가 소문자로 된 JavaBean의 이름, 즉game이 됩니다. 이 주석을 통해 애플리케이션은 보기의 EL 표현식을 사용하여 빈을 그 이름으로 지칭할 수 있습니다. - 15행의
@SessionScoped주석. 이것은 빈에 대한 범위를 지정하는 CDI 주석입니다. 모든 빈에는 인스턴스의 수명 주기와 다른 빈의 인스턴스에서 빈의 어떤 인스턴스를 볼 수 있게 할지 결정하는 범위가 있습니다.@SessionScoped주석은 이 빈이 세션 범위의 빈(즉, 빈의 수명 주기가 세션의 수명 주기라는 의미)임을 선언합니다. - 23행과 29행의
@Inject주석. 이것은 의존성 주입 지점, 즉 자바 클래스 또는 인터페이스에 대한 의존성을 주입할 수 있는 지점을 식별하는 데 사용되는 CDI 주석입니다. 23행에서 주석은maxNumber필드에 대한 의존성 주입 지점을 식별합니다. 23행은 주입하기 위한 구현을 식별하는 한정자 주석인@MaxNumber도 지정합니다. 한정자는 유형이 같은 개체들의 다른 사용 방법을 구분하는 데 도움이 되는 강력한 형식의 키입니다. 이번 팁의 후반부에 한정자에 대해 더 자세히 설명하겠습니다.@MaxNumber를 한정자 주석으로 정의하면 최대 추측 횟수에 대한 제한 값을 주입할 수 있습니다. 29행에서@Inject주석은randomNumber필드에 대한 의존성 주입 지점을 식별합니다. 29행은 주입하기 위한 구현을 식별하는 한정자 주석인@Random도 지정합니다.@Random을 한정자 주석으로 정의하면 사용자가 추측할 필요가 있는 임의의 수를 주입할 수 있습니다. - 72행의
@PostConstruct주석. 이 주석은 JSR 250, 자바 플랫폼용 공통 주석에 정의되어 있습니다. 이 주석은 구성 요소를 만든 후 초기화를 수행할 메소드를 식별하는 데 사용됩니다. 여기서reset()메소드는@PostConstruct주석으로 표시됩니다. 빈을 만든 후,reset()메소드는 나머지 추측 횟수를 추적하는remainingGuesses, 최대 추측 횟수에 대한 값을 유지하는biggest및 사용자가 추측할 필요가 있는 임의로 생성된 수를 유지하는number와 같은 많은 변수를 초기화합니다.
도움이 되는 주석
빈이 한정자 주석으로 @Random 및 @MaxNumber 주석을 사용하는 것을 보았습니다. 이제 그런 주석이 어떻게 정의되는지 살펴봅시다.
다음은 @Random 주석의 정의입니다.
15행의 @Qualifier 주석은 어떤 주석을 한정자 주석으로 식별하는 데 사용되는 자바용 의존성 주입 주석입니다. 한정자는 주입할 자바 클래스 또는 인터페이스의 특정 구현을 식별합니다. 한정자 주석을 사용하려면 우선 한정자로서 그 형식을 정의해야 합니다. 그렇게 하기 위해 @Qualifier 주석을 사용합니다. @Random을 한정자 주석으로 정의하면 임의의 수를 애플리케이션에 주입할 수 있습니다.
@Qualifier 주석은 아래에 표시된 것처럼 @MaxNumber 주석의 정의에도 사용됩니다.
16행의 @Qualifier 주석은 @MaxNumber를 한정자 주석으로 정의합니다. @MaxNumber를 한정자 주석으로 정의하면 최대 허용 추측 횟수를 애플리케이션에 주입할 수 있습니다.
유틸리티 빈
애플리케이션의 중요한 구성요소가 하나 더 있는데, 그것은 바로 Generator라는 이름의 유틸리티 빈입니다. Generator 빈은 다음과 같은 형태입니다.
다음은 빈에서 강조 표시된 주석이 하는 역할입니다.
- 7행의
@ApplicationScoped주석은 클래스에 대한 범위를 지정하는 CDI 주석입니다. 이 주석은Generator클래스의 인스턴스가 애플리케이션의 수명 주기 동안 존재함을 선언합니다. - 15행 및 18행의
@Produces주석은 어떤 메소드를 producer 메소드로 식별하는 데 사용되는 CDI 주석입니다. producer 메소드는 애플리케이션에 있는 다른 빈에서 주입된 개체를 필요로 할 때마다 호출됩니다. 15행에서 producer 메소드는next()입니다.Game빈이 다음 난수의 인스턴스를 구할 필요가 있을 때 Beans Manager에서 이 메소드를 호출합니다. 18행에서 producer 메소드는getMaxNumber()입니다.Game빈이 최대 허용 추측 횟수(이 경우에는 100)를 구할 필요가 있을 때 Beans Manager에서 이 메소드를 호출합니다.
구성요소가 함께 작동하는 방식
앞서 설명한 UI로 돌아가 봅시다. 사용자가 메시지에 응답하여 추측 버튼을 클릭하면 CDI 기술이 작동합니다. 자바 EE 컨테이너는 Game 빈과 Generator 빈의 상황별 인스턴스를 자동으로 인스턴스화합니다. Game 빈을 만든 후, 이 빈의 reset() 메소드가 호출되어 최대 추측 횟수에 대한 값을 유지하는 biggest 및 사용자가 추측할 필요가 있는 임의로 생성된 수를 유지하는 number와 같은 많은 변수를 초기화합니다.
Game 빈은 maxNumber 필드에서 최대 추측 횟수를 가져옵니다. 한정자 주석인 @MaxNumber를 포함한 의존성 주입 지점이 maxNumber 필드에 대해 지정된다는 점을 상기하십시오. Generator 빈에서 producer 메소드인 getMaxNumber()가 @MaxNumber 한정자 주석과 연관된다는 점도 상기하십시오. 결과적으로, Game 빈이 @MaxNumber 필드에 액세스할 때 이 빈은 Generator 빈의 getMaxNumber() 메소드를 호출합니다. getMaxNumber() 메소드는 maxNumber 필드의 값, 즉 100을 반환합니다.
Game 빈은 사용자가 추측할 임의의 수를 제공하기 위해 비슷한 경로를 거칩니다. 이 빈은 randomNumber.get() 메소드를 구성 후 초기화의 일부로 호출합니다. 한정자 주석인 @Random을 포함한 의존성 주입 지점은 randomNumber 필드에 대해 지정되고, Generator 빈의 producer 메소드인 getRandom()은 @Random 한정자 주석과 연관된다는 점을 상기하십시오. 결과적으로, Game 빈이 randomNumber.get() 메소드를 호출하면 Generator 빈의 getRandom() 메소드가 호출됩니다. randomNumber.get() 메소드는 java.util.Random 클래스의 getRandom() 메소드를 사용하여 0~100의 범위 내에서 임의의 수를 생성합니다.
샘플 코드 실행
샘플 애플리케이션이 이 팁에 제공됩니다. 샘플 애플리케이션을 실행하려면 다음과 같이 하십시오.
- 글래스피쉬 v3 프리뷰 애플리케이션 서버의 최신 promoted build 또는 nightly build를 아직 다운로드하지 않았으면 다운로드하십시오.
- 샘플 애플리케이션 패키지인 weld-guess.zip을 다운로드합니다.
- 샘플 애플리케이션 패키지의 압축을 풉니다. 애플리케이션 소스 코드가 들어 있는 폴더뿐 아니라, 애플리케이션의 WAR 파일인
weld-guess.war도 보일 것입니다. UI에 대한 소스 코드는web폴더에 있습니다. 빈과 주석에 대한 소스 코드는src폴더에 있습니다. - 다음 명령을 입력하여 글래스피쉬 v3 프리뷰 애플리케이션 서버를 시작합니다.
여기서
<GFv3_inst>/bin/asadmin start-domain
<GFv3_inst>는 글래스피쉬 v3 프리뷰 애플리케이션 서버를 설치한 곳입니다. weld-guess.war파일을<GFv3inst>/domains/domain1/autodeploy디렉토리에 복사하여 샘플 애플리케이션을 배포합니다.- 브라우저를 열고 URL http://localhost:8080/weld-guess에 액세스하여 애플리케이션을 실행합니다.
추가 자료
자세한 내용은 다음 자료를 참조하십시오.
- JSR 299: Contexts and Dependency Injection (CDI)
- JSR 330: Dependency Injection For Java
- JSR 314: JavaServer Faces 2.0
- JSR 250: Common Annotations for the Java Platform
- Context And Dependency Injection (JSR 299) and Servlets
저자 정보
Roger Kitain은 JavaServer Faces에 대한 공동 스펙 부문 리더입니다. 그는 1997년 이래 server-side 웹 기술 및 제품에 광범위하게 관여해 왔습니다. 2001년에는 레퍼런스 구현 팀의 일원으로 JavaServer Faces 기술에 대한 작업을 시작했습니다. 또한 서블릿 및 JSP 기술 관련 경험을 보유하고 있습니다. 최근에 Roger는 CDI 사양과 글래스피쉬 컨테이너와 CDI의 통합 프로젝트에 참여했습니다. Roger Kitain의 블로그를 둘러보십시오.
---------------------------------------------------------------------------------------
원문 :
Using CDI and Dependency Injection for Java in a JSF 2.0 Application
http://blogs.sun.com/enterprisetechtips ··· njection
"Java EE" 카테고리의 다른 글
- JAX-WS 핸들러 구성, 패키징, 배치하기 (댓글 2개 / 트랙백 0개) 2006/10/19
- Enterprise Bean에서 보안 주석 사용하기 (댓글 4개 / 트랙백 0개) 2007/05/28
- 엔터프라이즈용 Java Application Verification Kit, 2부 (댓글 1개 / 트랙백 0개) 2005/10/05
- Java Persistence를 최상으로 구현하는 방법 (댓글 12개 / 트랙백 0개) 2007/07/23
- SAAJ 소개 (댓글 1개 / 트랙백 0개) 2005/06/08
- 커스텀 ELResolver를 이용하여 통합 EL 확장하기 (댓글 4개 / 트랙백 0개) 2006/10/19
- JAX-WS를 이용한 웹 서비스 개발 (댓글 1개 / 트랙백 0개) 2006/01/18
- JAXR (JAVA API FOR XML REGISTRIES) (댓글 1개 / 트랙백 0개) 2005/05/18
- GlassFish에서 호출 흐름 모니터링하기 (댓글 3개 / 트랙백 0개) 2006/06/16
- Groovy, Grails, MySQL 및 Java Persistence API의 조합 (댓글 0개 / 트랙백 0개) 2008/08/20
댓글을 달아 주세요