요약이 기사는 주석과 측면의 힘을 결합하여 선언 서비스를 EJB 3.0과 호환되는 방식으로 컨테이너 독립성을 제공하는 방법을 결합하는 방법에 대해 논의 할 것입니다.
1. 소개
소프트웨어 개발의 생산 성능을 더욱 향상시킬 수있는 방법을 공동으로 추구하면서, 우리는 Java 커뮤니티의 구성원으로서 일반적으로 J2EE를 방문하여 분산 거래 관리, 동시성 및 객체 배포 솔루션과 같은 엔터프라이즈 개발에서보다 어려운 기술 문제를 제공합니다. 이 복잡한 엔터프라이즈 서비스는 애플리케이션 서버 공급 업체가 구현할 수 있으며 상업 개발자가 균형을 잡을 수있는 이데올로기가 이데올로기를 구현할 수 있습니다. 실제로 좋은 생각입니다. J2EE, 특히 EJB는 Enterprise Java 응용 프로그램이 구축되는 플랫폼을 성공적으로 제공했습니다.
이 성공의 일부는 프로그램을 개발하는 방법 인 선언 프로그래밍을 수행 할 수있는 능력 때문입니다.이 프로그램은 코드가 모든 곳에 퍼지도록 비즈니스 로직으로 명시 적으로 인코딩하는 대신 인프라 서비스를 선언 할 수 있기 때문입니다. EJB는이 프로그래밍 접근법의 가치를 입증했습니다. 거래 및 보안과 같은 엔터프라이즈 문제가 게시 된 디스크립터로 선언되고 컨테이너로 처리 할 수 있습니다.
그러나 지난 몇 년 동안 점점 더 많은 개발자들이 EJB가 팀의 생산성에 많은 새로운 도전을 가져다 준다는 것을 깨달았습니다. 각 EJB는 JNDI 등을 통해 액세스 한 서사 설명서와 함께 여러 인터페이스를 동반해야합니다. 컨테이너 외부의 EJB에서의 단위 테스트는 또한 추가적인 어려움을 가져옵니다.
이 기사를 읽으려면 다음 도구가 있어야합니다.
· Java 2 SDK 1.5
· Maven 2.0 베타 2
EJB 3.0의 목표는 다음과 같은 측면에서 엔터프라이즈 개발을 더 쉽게 만드는 것입니다.
· 메타 데이터 주석을 도입하여 엔터프라이즈 서비스에 대한 선언적 요청 구현
· 주석을 통해 종속성/자원 주입을 구현합니다
· 엔터프라이즈 콩 및 EJB 특정 인터페이스의 분리 구현
· 가벼운 객체 관계 매핑을 통한 연속 스토리지의 단순화
이것은 EJB 개발자들에게 봄 바람과 같습니다. 그들은 EJB를 개발, 테스트 및 유지하기 위해 열심히 노력하고 있습니다. EJB 3.0을 사용하여 EJB 3.0을 사용하여 엔터프라이즈 콩을 작성하는 것은 쉽습니다. EJB로 표시하고 엔터프라이즈 서비스를 요청하는 특정 주석이있는 Pojo (전통적인 Java 객체)를 만드는 것과 마찬가지로. 다음은 EJB 3.0 공개 초안의 EJB의 예입니다.
@stateful
공개 클래스 카트 빈은 쇼핑 카트를 구현합니다
{
개인 플로트 총계;
개인 벡터 제품 코드;
public int someshoppingmethod () {...};
...
}
EJB 3.0 성명서는 본질적으로 개발자가 필요로하는 것은 "모든 것을 만족시키는 하나의 릴리스"가 아니라 가볍고 사용하기 쉬운 솔루션으로 개발자에게 특정 엔터프라이즈 서비스를 제공한다고 말합니다. 이를 위해 EJB 3.0에서 제공하는 가장 중요한 방법 중 하나는 Enterprise Beans 및 EJB API를 분리하는 것입니다. 이 솔루션은 흥미로운 파생 상품을 제공합니다. EJB는 이제 다른 EJB 컨테이너뿐만 아니라 모든 응용 프로그램 프레임 워크 내부에서도 실행될 수 있습니다. .
이 기사는 선언 프로그래밍, EJB, 측면 또는 주석에 대한 심층적 인 탐색을 제공하지 않습니다. 대신, 이러한 기술 간의 상호 관계를 분석하고 응용 프로그램 개발을 단순화하기 위해 새로운 방식으로이를 결합하는 방법에 대해 논의하십시오.
이 기사에서는 EJB 3.0 호환 Bean을 작성하는 방법을 배우고 선언적 거래 관리, 보안 및 자원 주입을 선언하기 위해 몇 가지 간단한 측면을 만듭니다. 이 연습에서 혜택을 누릴 수 있기를 바랍니다.
· 학습의 세 가지 실제 응용 (종속성 주입, 보안 및 거래).
· EJB 3.0과 그 뒤에있는 아이디어에 익숙합니다.
EJB 3.0 호환 서비스를 EJB에서만 제공하지 않고 경량으로 구현할 수 있도록 특정 API에서 EJB의 디커플링을 구현하는 방법을 인식하십시오.
2. 예제 응용 프로그램-비행 순서
토론 전체에서, 당신은 의존성 주입, 보안 및 거래 관리를 구현하기 위해 측면과 주석을 사용하는 비행 순서 시스템의 구현에 대해 배웁니다. 이 앱은 두 가지 기능 만 수행합니다. 사용자는 항공편을 검색 한 다음 여행을 주문할 수 있습니다 (그림 2). 식별 된 사용자 만 수행 할 수 있도록 두 작업 모두 안전하게 처리됩니다. 또한 "주문 여행"운영에는 두 개의 항공편 (출력 및 반품 항공편)을 주문하는 것이 포함되므로 작업은 트랜잭션으로 생성되어야합니다 (예 : 두 주문은 작업 단위로 성공하거나 실패합니다.
그림 1. 비행 쿼리 : 첫째, 사용자는 지정된 기준을 충족하는 항공편을 찾습니다.
그림 2. 비행 주문 : 다음으로, 사용자는 아웃 바운드 항공편과 반환 비행을 주문합니다. 두 주문 모두 성공하거나 실패합니다.
이 간단한 웹 응용 프로그램에는 여러 서블릿, 서비스 모양 및 DAO 레이어가 포함되어 있습니다 (그림 3 참조).
자원 구성, 보안 및 거래 관리와 같은 문제를 교차 절단하는 것은 Java 5 주석으로 선언 된 주입 동작을 구현하기 위해 측면 (SAGION 1.5 M3과 함께 구현)에 의해 제공됩니다.
그림 3. 비행 순서 시스템 아키텍처 :이 비행 순서 시스템은 세 가지 주요 구성 요소로 구성되어 있으며, 이들은 함께 가입하여 사용자 요청을 완료합니다. 3. 자원 주입
EJB 3.0 초안 선언은 @Resource 주석을 통해 리소스를 선언 할 수 있으며 (이 결정은 일반 주석 선언 초안에 정의 됨) 컨테이너별로 EJB에 주입됩니다. 의존성 주입은 기술입니다.이 기술을 사용하여 해당 객체에 대해 명시 적으로 생성 된 엔티티가 아닌 객체의 종속성을 제공 할 수있는 엔티티가 아닌 객체 외부의 엔티티를 사용합니다. 그것은 때때로 할리우드 원칙으로 묘사됩니다. "우리는 전화하지 마십시오. 우리는 전화 할 것입니다."
TravelAgencyServiceImpl 클래스를 예로 들어 보자 - 일부 데이터를 지속적으로 저장하려면이 클래스는 iflightDao 인터페이스의 구현을 찾아야합니다. 전통적으로 이것은 공장, 싱글 톤, 서비스 로케이터 또는 기타 맞춤형 솔루션을 통해 달성됩니다. 그중 하나는 가능한 한 가지 솔루션이 다음과 같습니다.
Public Class TravelAgencyServiceImpl은 IttravelAgencyService를 구현합니다
{
공개 iflightdao flightdao;
public travelagencyserviceimpl ()
{flightDao = flightDaofactory.getInstance (). getFlightDao ();
공개 void booktrip (긴 아웃 바운드 플라이트, 긴 반품, int 좌석)
InvalidseatSexception을 던집니다
{
REBLAYSEATS (OutboundFlightID, 좌석);
REPLAYSEATS (ReturnFlightId, 좌석);
}
}
이 구현에는 특정 공장 클래스를 만드는 것이 포함된다는 것을 알았습니다. IflightDao를 생성하기위한 구현을 이해하기 위해 어딘가에 저장된 구성 정보를 읽을 수 있습니다. 서비스가 컨테이너에 의해 주입 된 종속성을 명시 적으로 생성하지 않으면 구성 세부 사항 및 객체 작성이 컨테이너로 프록시됩니다. 이를 통해 응용 프로그램의 구성 요소는 다른 구성으로 쉽게 연결할 수 있으며 구식 싱글 톤 및 공장 코드를 많이 제거합니다.
JSR 250 리소스 주석으로 선언 된 iflightdao의 구현에 의존하는 클래스 구현은 다음과 같습니다.
Public Class TravelAgencyServiceImpl은 IttravelAgencyService를 구현합니다
{
@Resource (이름 = "FlightDao")
공개 iflightdao flightdao;
공개 void booktrip (긴 아웃 바운드 플라이트, 긴 반품, int 좌석)
InvalidseatSexception을 던집니다
{
REBLAYSEATS (OutboundFlightID, 좌석);
REPLAYSEATS (ReturnFlightId, 좌석);
}
}
이 경우 컨테이너는 서비스 클래스에 "FlightDao"라는 리소스의 올바른 구현을 제공합니다. 그러나 EJB 3.0 릴리스를 기다리는 대신 지금 자원 주입을 활용하려면 어떻게해야합니까? 좋아, 가벼운 컨테이너를 가져갈 수 있습니다. 스프링 또는 피코 컨테이너와 같은 종속성 주입을 제공 할 수 있습니다. 그러나 가벼운 컨테이너가 있다는 것을 이해하지 못합니다. JSR 250 리소스 주석을 사용하여 주입 요구 사항을 지정할 수 있습니다 (이와 관련하여 일부를 기대하고 있지만).
한 가지 해결책은 측면을 사용하여 종속성 주입을 구현하는 것입니다. 이를 위해 @Resource 주석을 사용하는 경우 구현은 EJB 3.0 웨이와 일치하며 EJB 3.0 구현과 호환되며 이는 구현하기가 그리 어렵지 않습니다. 다음 목록은 @Resource 주석으로 주석이 붙은 필드를 주입하는 측면을 보여줍니다.
@측면
공공 계급 주입자
{
Private DependencyManager Manager = 새 종속성 관리자 ();
@Before ( "get (@Resource * *. *)")
Public Void effiendAccesses (joinpoint thisjoinpoint)
불법적 인 exception, 불법 행정 지출을 던졌습니다
{
FieldSignature Signature = (FieldSignature) thisjoinpoint.getSignature ();
리소스 인젝트 otantation = signature.getfield (). getAnnotation (resource.class);
객체 종속성 = manager.resolve 종속성 (signature.getFieldType (), injectAnnotation.name ());
signature.getfield (). set (thisjoinpoint.getThis (), 종속성);
}
}
이 간단한 측면은 모든 속성 파일에서 구현 클래스를 쿼리하고 (이 논리는 종속성 관리자 개체에 캡슐화 됨) 필드에 액세스하기 전에 @Resource 주석으로 주석이 달린 필드에 주입하는 것입니다. 분명히이 구현은 완전하지 않지만 EJB없이 JSR 250 호환 방식으로 자원 주입을 제공 할 수있는 방법을 보여줍니다.
4. 안전
자원 주입 외에도 JSR 250 및 EJB 3.0은 주석을 통해 메타 데이터 보안 표현을 제공합니다. javax.annotation.security 패키지는 보안 요구 사항을 정의하기위한 방법에 적용될 수있는 5 가지 주석 (runas, robolested, permitall, denyall 및 rodolereferenced)을 정의합니다. 예를 들어, 위에 나열된 BookFlight 메소드가 "사용자"역할을 가진 발신자 만 실행할 수 있다고 선언하려면 다음 보안 제약 조건 으로이 메소드에 주석을 달 수 있습니다.
Public Class TravelAgencyServiceImpl은 IttravelAgencyService를 구현합니다
{
@Resource (이름 = "FlightDao")
공개 iflightdao flightdao;
@rolesallowed ( "사용자")
공개 void booktrip (긴 아웃 바운드 플라이트, 긴 반품, int 좌석)
InvalidseatSexception을 던집니다
{
REBLAYSEATS (OutboundFlightID, 좌석);
REPLAYSEATS (ReturnFlightId, 좌석);
}
}
이 주석은 컨테이너가 지정된 역할의 발신자만이 방법을 실행할 수 있도록 책임을 져야한다고 명시합니다. 이제 또 다른 간단한 측면을 보여줄 것입니다. 응용 프로그램의 보안 제약을 더욱 강화할 것입니다.
@측면
공공 계급 보안 관습
{
@around ( "실행 (@javax.annotation.security.rolesallowed *. *(..))") ")
주변의 공개 대상은 Methods (Proceedingjoinpoint이 Joinpoint)
던질 수 있습니다
{
부울 callerauthorized = false;
relallowed rosallowed = rolesallowedforjoinpoint (thisjoinpoint);
for (문자열 역할 : Rolesallowed.value ())
{
if (callerinrole (역할))
{callerauthorized = true}
}
if (callerauthorized)
{return thisjoinpoint.proceed ();
또 다른
{
새로운 runtimeexception ( "지정된 기능을 수행 할 권한이없는 발신자");
}
}
개인 rosallowed roboleslowedforjoinpoint (ProceedingJoinPoint이 JoinPoint)
{
MethodSignature MethodSignature = (MethodSignature) thisjoinpoint.getSignature ();
메소드 targetMethod = methodSignature.getMethod ();
return targetmethod.getAntOntation (rolesallowed.class);
}
개인 부울 발신자 (문자열 역할)
{...}
}
이 측면에는 모든 방법의 실행이 포함됩니다. 발신자가 주석에 지정된 역할 중 하나이며 @RolesalLowned 주석에 주석을 달고 발신자가 메소드를 호출 할 권한이 있는지 확인합니다. 물론 사용자를 승인하고 JAAS 또는 맞춤형 솔루션과 같은 역할을 검색하기 위해 원하는 알고리즘을 사용할 수도 있습니다. 이 예제 프로그램에서 편의를 위해 서블릿 컨테이너로 프록시를 선택했습니다.
V. 업무
거래는 엔터프라이즈 개발의 중요한 부분이됩니다. 동시 환경에서 데이터 통합을 용이하게하기 때문입니다. 높은 수준에서 트랜잭션은 여러 또는 완전한 또는 불완전한 작업을 통해이를 보장 할 수 있습니다.
자원 주입 및 보안에 대한 주석과 달리 트랜잭션에 대한 주석은 EJB 3.0에만 해당되며 JSR 250 정상 주석에는 정의되지 않습니다. EJB 3.0은 트랜잭션 관리 및 트랜잭션 기능의 트랜잭션과 관련된 두 가지 주석을 정의합니다. TransactionManager 주석은 트랜잭션이 컨테이너 또는 Bean에 의해 관리되는지 여부를 지정합니다. EJB 3 에서이 주석이 지정되지 않으면 컨테이너가 관리하는 트랜잭션이 사용됩니다. TransactionAttribute 주석은 메소드의 트랜잭션 전파 수준을 지정하는 데 사용됩니다. 필수, 요구, 요구, 신규, 지원, 지원 및 지원되지 않는 유효한 가치는 기존 거래가 필요한지 또는 새로운 트랜잭션이 시작되는지 여부를 정의하는 데 사용됩니다.
책 비행 작업은 트랜잭션에 포장하여 아웃 바운드 항공편과 반품 비행의 두 단계로 구성되므로 운영의 일관성을 보장 할 수 있습니다. EJB 3.0 트랜잭션 주석을 사용하면 다음과 같습니다.
Public Class TravelAgencyServiceImpl은 IttravelAgencyService를 구현합니다
{
@Resource (이름 = "FlightDao")
공개 iflightdao flightdao;
@rolesallowed ( "사용자")
@transactionAttribute (TransactionAttributeType.Required)
공개 void booktrip (긴 아웃 바운드 플라이트, 긴 반품, int 좌석)
InvalidseatSexception을 던집니다
{
REBLAYSEATS (OutboundFlightID, 좌석);
REPLAYSEATS (ReturnFlightId, 좌석);
}
}
거래 경계를 자동으로 정의하기 위해 간단한 측면을 적용 할 수 있습니다.
@측면
공개 클래스 트랜잭션 사례
{
@PointCut ( "실행 (@javax.ejb.transactionAttribute * *. *(..))")
public void transactionalMethods () {}
@before ( "transactionalMethods ()")
public void beforetransactionalmethods ()
{hibernateutil.begintransaction ();
@AfterReturning ( "transactionalMethods ()")
공개 void attreturningtransactionalMethods ()
{hibernateutil.committransaction ();
@AfterThrowing ( "transactionalMethods ()")
ThrowingTransactionAlmethods () 후 공개 void
{hibernateutil.rollbacktransaction ();
}
이 구현은 최대 절전 모드 및 유비쿼터스 스레드-로컬 패턴이 최대 절전 모드 세션 및 트랜잭션 개체를 관리하는 데 사용된다는 가정을 기반으로합니다.
6. 요약
EJB 3.0 및 JSR 250 주석 세트를 사용 함으로써이 기사는 자원 관리, 보안 및 트랜잭션과 같은 문제가 어떻게 측면으로 구현되는지를 보여주었습니다. 물론, 우리가 더 배워야 할 다른 많은 내용이 있습니다. 가장 먼저 배울 수있는 것은 측면 J를 사용하여 이러한 예제 측면을 구현함으로써 모듈 식 교차 절단 문제가 제공하는 청사진입니다. 둘째, 우리는 EJB 3.0 진술 뒤에 새로운 아이디어와 개념을 보았습니다. 마지막으로, 우리는 또한 EJB API에서 비즈니스 객체를 분리하기 위해 제공되어야하는 자유를 극적인 방식으로 볼 수 있습니다. 이 시점에서 TravelAgencyServiceImpl로 만들고 싶은 것은 마지막 메모를 추가하는 것입니다.
@stateful
Public Class TravelAgencyServiceImpl은 IttravelAgencyService를 구현합니다
{...}
마지막으로, 나는 엔터프라이즈 서비스를 제공하기위한이 무료 접근 방식이 프레임 워크/컨테이너 산업에서 경쟁과 혁신을 가져 오기를 바랍니다.