Enterprise JavaBeans 3.0 Java EE 5.0 Business Tier Component Technology 김병곤 fharenheit@j2eearchitect.net / @gmail.com
Enterprise JavaBeans 3.0 Java EE 의핵심비즈니스컴포넌트구현기술 기존의 EJB 2.x 는 Heavy 한 Object 로 EJB 가구현 EJB 3.0 은 POJO(Plain Old Java Object) 기반으로 lightweight 하게구현 Java SE 5 을기반으로하여손쉽고빠르게개발이가능해짐 배포및모든과정이아무간결하고편리함 AOP 의일부분기능은 Interceptor 가추가됨 2
Contents Enterprise JavaBeans 3.0 Overview Session Bean Entity Bean( 생략 ) Message-Driven Bean과 Java Message Service Interceptor Transaction & Exception Timer Service WebService 3
Enterprise JavaBeans 3.0 관련도서 해외원서 Pro EJB 3 Java Persistence API, Apress Beginning EJB 3 Application Development, Apress EJB 3 In Action, Manning Enterprise JavaBeans 3.0 5 th, Oreilly Mastering Enterprise JavaBeans 4 th, Wiley 국내 Enterprise JavaBeans, 가메출판사, 김병곤 http://kangcom.com/common/bookinfo/bookinfo.asp?sku= 200609040001 4
도서소개 Enterprise JavaBeans 3.0 출판사 : 가메출판사 저자 : 김병곤 쪽수 : 548 발간일 : 2006-9-4 특징 국내최초 EJB 3.0 도서 개념위주설명도서 JBoss 기반 JDK 5 에대한기본설명포함 EJB JPA 에대한상세한설명으로 ORM 기반자바애플리케이션을구현하는독자에게유용 5
EJB 3.0 Overview Java EE 5.0 Business Tier Component Technology 김병곤 fharenheit@j2eearchitect.net / @gmail.com
Java EE 5 의개요 J2SE 는분명히스탠드얼론애플리케이션을개발하는데좋은환 경을제공하였지만미션크리티컬한비즈니스애플리케이션을구현하기에는너무나부족한것이많았다 (1995년) J2EE 는 (1998 년 ) 가장견고하고정교한분산엔터프라이즈애플리케이션의모델 대규모이면서 확장가능하고 보안기능이필요한애플리케이션을개발하는데필수적인기술 7
분산 n-tier 아키텍처 2-Tier 아키텍처 3-Tier 아키텍처 8
분산 n-tier 아키텍처 J2EE 로구현한 n-tier 아키텍처 Client Tier Presentation Tier Business Tier Integration Tier Resource Tier 웹브라우저 웹서버 웹컨테이너 EJB 컨테이너 웹브라우저 자바애플릿 HTML 동영상 플래쉬이미지 JSPs Servlet EJB EJB EJB EJB Legacy System 애플리케이션 JNDI EJB 데이터베이스 9
Java EE 5 의구조 10
n-tier 구조의문제점 n-tier로전체애플리케이션을모듈화시켜서분산시키면분명히이득을보는것은사실이나이렇게모듈화함으로써발생하는문제도있다. 분산된애플리케이션을통합하는데많은노력이필요하다. 분산된시스템의리소스관리가어렵다. 분산된애플리케이션의변경이발생할때의존적인시스템이영향을받는다. 분산된애플리케이션은디버깅이매우어렵다. 분산된시스템의장애발생시원인규명이어렵다. 오늘날거의대부분의유지보수비용은바로위와같은문제를해결하는데집중되어있다. 11
애플리케이션컴포넌트 애플리케이션클라이언트 ( 스탠스얼론자바클라이언트 ) 애플릿 ( 웹브라우저에서실행하는자바코드 ) 웹컴포넌트 (JSP, Servlet, JSF) Presentation Tier 에서구동하며요청및화면을처리 서버컴포넌트 (Enterprise JavaBeans) 비즈니스로직을처리하기위한핵심분산컴포넌트기술 Business Tier에서동작 종류 Session Bean Stateless Session Bean Stateful Session Bean Entity Bean Message-Driven Bean 12
Java EE 5 의구성요소와버전 JSP(Java Server Pages) 2.1 Servlet 2.5 JSF(Java Server Faces) 1.2 JSTL 1.2 Java Mail 1.4 Java Message Service(JMS) 1.1 Java Persistence 1.0 Web Service 1.2 JAXP Enterprise JavaBeans 3.0 JTA 1.1 JNDI Connector 1.5 JDBC 3.0 13
왜 Enterprise JavaBeans 를사용하는가? Enterprise JavaBeans 는 J2EE 플랫폼에속하는표준이다. Enterprise JavaBeans 는트랜잭션을지원한다. Enterprise JavaBeans 는보안을지원한다. Enterprise JavaBeans 는재사용가능한컴포넌트다. 14
EJB 컨테이너의기능 트랜잭션관리 분산트랜잭션을지원하여하나이상의 EJB, DB, Legacy 를단일트랜잭션으로처리 인증과접근제어 메소드호출에대해서 Authentication 과 Authorization 을지원 EJB 인스턴스풀링 빈의인스턴스를풀링하여많은사용자에대한요청을처리 세션관리 Stateful Session Bean 을통한사용자의정보를유지 지속성메커니즘 Java Persistence API 를이용하여 Entity Bean 을구현 (ORM) 데이터베이스커넥션풀링 15
Enterprise JavaBeans 의종류 J2EE Server( 웹애플리케이션서버 ) JNDI Naming Service 웹서비스 Connector Web Container 리소스검색 호출 EJB Container 세션빈 원격호출 외부서버 요청 JSPs 세션빈 사용 데이터베이스처리 클라이언트 웹서버 Servlet Servlet 호출 메일송신 메시지송신 메시지드리븐빈 엔티티빈 데이터베이스처리 데이터베이스처리 데이터베이스 Java Mail Java Message Service 메시지송신 16
Enterprise JavaBeans 의종류 Session Bean Stateless Session Bean 클라이언트의정보를유지하지않는빈. 인스턴스풀을사용. Stateful Session Bean 클라이언트의정보를유지하는빈. 인스턴스캐쉬를사용. 클라이언트당하나씩생성됨 Entity Bean 데이터베이스테이블과객체를매핑하는 Object-Relational Mapping(ORM) 빈 완전한 POJO 기반 Message-Driven Bean 비동기메시지를수신하여처리하는빈 17
Enterprise Beans 의비즈니스인터페이스 엔터프라이즈빈즈는비즈니스인터페이스를통해비즈니스로직을정의한다. 호출위치에따라로컬 / 리모트인터페이스로구분한다. 18
EJB 3.0 의특징 - 로컬과리모트호출 19
EJB 3.0 의특징 인스턴스풀링 EJB 에서는인스턴스풀링을통하여많은사용자의요청을동시 에처리한다. 20
EJB 3.0 의특징 - 콜백메소드 EJB 3.0 에서 Stateless Session Bean 의생명주기 존재하지않는상태 1. newinstance() 2. Dependency Injection 3. @PostConstruct 콜백 @PreDestory 콜백 비즈니스메소드 타임아웃콜백 21
EJB 3.0 의특징 - 콜백메소드 EJB 컨테이너는빈의생명주기를관리하기위해서적절한시점 에콜백메소드를호출한다. 콜백메소드종류 설명 @PreDestroy 빈인스턴스를삭제한이후에컨테이너가호출하는콜백메소드 @PostContruct @PrePassivate @PostActivate 빈인스턴스가생성된직후에컨테이너가호출하는콜백메소드 빈인스턴스가 passivate 되어 2 차저장소에저장되기전에호출하는콜백메소드 Passivate 된빈인스턴스가 activate 된후에호출하는콜백메소드 EJB 2.x 에서는무조건콜백메소드를사용하도록정의했지만 EJB 3.0 에서는필요한경우에만사용할수있다. 22
EJB 3.0 의특징 - 콜백메소드 컨테이너는적절한시점에서이콜백메소드를호출한다. @Stateful public class ShoppingCartBean implements ShoppingCart {... 생략 @PostConstruct public void dopostconstruct() { System.out.println(" 장바구니를생성합니다."); @PreDestroy public void dopredestroy() { System.out.println(" 장바구니를삭제합니다."); // 여기에서주로사용하던자원을해제한다.... 생략 23
EJB 3.0 의특징 - 트랜잭션처리 EJB 컨테이너는다양한빈과다양한리소스에대한처리를단일 트랜잭션으로처리하게한다. 24
EJB 3.0 의특징 - Interceptor EJB 3.0에서는메소드의호출을가로채어처리하는 Interceptor 가새로추가되었다. @Stateless public class InterceptorHelloBean implements InterceptorHello { public void sayhello() { System.out.println("Hello EJB 3.0~!"); @AroundInvoke public Object myinterceptor(invocationcontext ctx) throws Exception { System.out.println("Interceptor가호출되었습니다."); // 계속 HelloWorldBean의비즈니스메소드를실행합니다. return ctx.proceed(); Spring Framework의 AOP(Aspect-Oriented Programming) 을기억하지는지. 25
EJB 3.0 의특징 - 타이머서비스 EJB 2.1 에서추가된타이머서비스는 EJB 에서스케줄러기능을 수행할수있게한다. @Stateless public class SimpleTimer implements SimpleTimerRemote { @Resource private javax.ejb.timerservice timer; // Dependency Injection public void calltimer(long milliseconds) { timer.createtimer(new Date(new Date().getTime() + milliseconds), "Hello World");... 생략 26
EJB 3.0 의변화 - 홈인터페이스는더이상없다. EJB 2.x 에서는 EJB 빈의인스턴스를생성하는 Home Interface 가존재 EJB 3.0 에서는홈인터페이스는더이상없다. 27
EJB 3.0 의변화 - 홈인터페이스는더이상없다. EJB 2.x 의홈인터페이스 빈의인스턴스를생성 public interface HelloHome extends EJBHome { public HelloObject create() throws RemoteException, CreateException; EJB 2.x 의리모트 ( 컴포넌트 ) 인터페이스 비즈니스로직정의 public interface HelloObject extends EJBObject { public String sayhello() throws RemoteException; 28
EJB 3.0 의변화 - 홈인터페이스는더이상없다. EJB 2.x 에서빈을정의 브즈니스인터페이스의구현 public class HelloBean implements HelloObject { private SessionContext sessioncontext; public void ejbcreate() { public void ejbremove() { public void ejbactivate() { public void ejbpassivate() { public void setsessioncontext(sessioncontext sessioncontext) { this.sessioncontext = sessioncontext; public String sayhello() throws java.rmi.remoteexception { return "Hello EJB World"; EJB 호출클라이언트 Context ctx = new InitialContext(); Object obj = ctx.lookup("hello"); HelloHome ejbhome = (HelloHome) PortableRemoteObject.narrow(obj, HelloHome.class); // 홈인터페이스 HelloObject ejbobject = ejbhome.create(); // 리모트인터페이스 String message = ejbobject.sayhello(); System.out.println( message ); 29
EJB 3.0 의변화 - 홈인터페이스는더이상없다. EJB 3.x 는 POJO 기반으로코딩하고홈인터페이스도없다. @Remote public interface HelloObject { public String sayhello(); 빈의구현코드 @Stateless public class HelloBean implements HelloObject { public String sayhello() { return "Hello EJB World"; EJB 호출클라이언트 Context ctx = new InitialContext(); HelloObject ejbobject = (HelloObject) ctx.lookup("hello"); String message = ejbobject.sayhello(); System.out.println( message ); 30
EJB 3.0 의변화 비즈니스인터페이스의출현 EJB 3.0에서는컴포넌트인터페이스대신비즈니스인터페이스가새로정의됨 EJB 2.x 의리모트 ( 컴포넌트 ) 인터페이스 public interface HelloObject extends EJBObject { // EJB 2.x 방식 public String sayhello() throws RemoteException; EJB 3.0 의리모트 ( 비즈니스 ) 인터페이스 @Remote public interface HelloObject { // EJB 3.0 방식 public String sayhello(); 31
EJB 3.0 의변화 Java SE 5 Annotation 의활용 EJB 3.0에서는기존에작성하던배포디스크립터 XML 파일을작성하지않고 Java SE 5 Annotation을대체하여기술한다. @Stateful @Remote(Posting.class) @TransactionManagement(TransactionManagementType.CONTAINER) public class PostingBean implements Posting {... 생략 public void something(){... 생략 ** 참고 : 배포디스크립터를작성해도상관은없음. 32
EJB 3.0 의변화 Dependency Injection Dependency Injection 을이용한필요자원의참조를컨테이너 의역할로변환 33
EJB 3.0 의변화 Dependency Injection EJB 2.x 에서는관련된자원을참조하기위해서는 JNDI Lookup 을수행하였다. @Stateless public class EnterpriseBeanA implements EnterpriseA { EnterpriseB b; public void callenterprisebeanb() { Context ctx = new InitialContext(); b = (EnterpriseB) ctx.lookup("enterprisebeana/local"); b.something(); @Stateless public class EnterpriseBeanB implements EnterpriseB { DataSource ds; public void something() { Context ctx = new InitialContext(); ds = (DataSource) ctx.lookup("java:oracleds"); Connection con = ds.getconnection(); // JDBC 커넥션획득 // JDBC 처리... 34
EJB 3.0 의변화 Dependency Injection EJB 3.0에서는 Dependency Injection을활용해서참조하는자원을 annotation으로기술하면컨테이너가처리한다. @Stateless public class EnterpriseBeanA implements EnterpriseA { @EJB EnterpriseB b; // Dependency Injection public void callenterprisebeanb() { b.something(); @Stateless public class EnterpriseBeanB implements EnterpriseB { @Resource(mappedName="java:OracleDS") DataSource ds; public void something() { Connection con = ds.getconnection(); // JDBC 커넥션획득 // JDBC 처리... 35
EJB 3.0 의변화 POJO 기반의엔터프라이즈빈 @Stateless public class CalculatorBean implements Calculator { public int add(int a, int b) { return a + b; public int sub(int a, int b) { return a - b; public int mul(int a, int b) { return a * b; public int div(int a, int b) throws DivisionByZeroException { System.out.println("b == " + b); if (b == 0) { throw new DivisionByZeroException("0으로나눌수없습니다 "); return a / b; 36
EJB 3.0 의변화 POJO 기반의엔터프라이즈빈 @Entity @Table(name = "PERSON") public class Person implements Serializable { public static enum Gender { MALE, FEMALE ; private String name; protected Person() { @Id @Column(name = "NAME") public String getname() { return name; public void setname(string name) { this.name = name; 37
EJB 3.0 의변화 새로운 Java Persistence API Entity Bean 을 Hibernate 를모델로하여완전하게재설계 @Entity public class Subject implements Serializable { private int subject_id; // Subject ID private String name; // Subject Name private Subject parent; // 부모 Subject public Subject() { @Id public int getsubject_id() { return subject_id; @OneToOne @JoinColumn(name = "parent_id") public Subject getparent() { return parent;... 생략 CREATE TABLE SUBJECT( SUBJECT_ID NUMBER NOT NULL, PARENT_ID NUMBER, NAME VARCHAR2(32) NOT NULL, CONSTRAINT P PRIMARY KEY (SUBJECT_ID) ); ALTER TABLE SUBJECT ADD CONSTRAINT P FOREIGN KEY (PARENT_ID) REFERENCES SUBJECT(SUBJECT_ID); 38
Summary EJB 3.0 은 Java SE 5 의새로운기능을적극적으로활용 기존의 EJB 에비해서가볍고, 쉽고빠르게개발할수있도록전체를재정의 POJO 기반으로매우간결하고쉽게 Enterprise Bean Component 를정의 Dependency Injection 을이용한의존성정보의자동주입 Domain Model 을 POJO 기반으로 DB 와 mapping 하는새로운개념의 Entity Bean 39
Q & A Q & A 40
EJB 3.0 Session Bean Java EE 5.0 Business Tier Component Technology 김병곤 fharenheit@j2eearchitect.net / @gmail.com
Session Bean Enterprise JavaBeans 를구성하고있는 Enterprise Bean 의하 나 비즈니스로직을처리하는핵심빈 EJB 프로젝트에서전체의 90% 이상을구성하고있는빈 상태유지여부에따라서다음과같이구분 Stateless Session Bean Stateful Session Bean 42
Session Bean Session Bean 은비즈니스로직을수행하는핵심 Enterprise Bean 이며동시에 Façade 로써동작한다. EJB Container 호출 세션빈 원격호출 웹서비스 호출 세션빈 사용 데이터베이스처리 클라이언트 메일송신 메시지송신 메시지드리븐빈 엔티티빈 데이터베이스처리 데이터베이스처리 데이터베이스 Java Mail 메시지송신 JMS Queue 43
Session Bean 의 Business Interface 실제비즈니스로직이정의되어있는단순인터페이스 원격호출여부에따라서다음과같이구분됨 Local Interface 동일 JVM, 동일컨테이너상에서호출할때 Remote Interface 서로다른 JVM 에서호출할때 EJB 2.x 에서는 Component Interface(Remote Interface + Local Interface) 라고불렀음 44
Session Bean 의 Business Interface 클라이언트는비즈니스인터페이스를호출하여로직을수행 클라이언트 호출 비즈니스인터페이스 세션빈 빈구현코드 가장단순한인터페이스로구현 public interface Calculator { int add(int a, int b); int sub(int a, int b); int mul(int a, int b); int div(int a, int b); 45
Remote Interface 와 Local Interface 원격호출시 Session Bean 은 Remote Interface 를가진다. 동일 JVM 에서호출시 Session Bean 은 Local Interface 를가진 다. 클라이언트 원격호출 리모트인터페이스 세션빈 빈구현코드 로컬호출 로컬인터페이스 세션빈 빈구현코드 46
Remote Interface 와 Local Interface 47
Business Interface 의제약사항 하나의 Session Bean 은 Remote Interface 와 Local Interface 를모두가질수있다. Remote Interface(Call By Value) 는 RMI 방식으로처리하므로 fine-grained 호출을수행하는경우성능에좋지못한영향을미 친다. 동일 JVM 에서 Remote Interface 를하나이상의 Session Bean 이호출하는경우벤더에서제공하는기능에따라서로컬호출 (Call By Reference) 을수행한다. 48
Remote Interface 의정의 Remote Interface 는 @Remote annotation 으로기술한다. @Remote public interface CalculatorRemote { int add(int a, int b); int sub(int a, int b); int mul(int a, int b); int div(int a, int b); Local Interface 는 @Local annotation 으로기술한다. @Local public interface CalculatorLocal { int add(int a, int b); int sub(int a, int b); int mul(int a, int b); int div(int a, int b); 49
Session Bean 구현클래스 Session Bean 의구현클래스는 POJO 기반으로구현한다. @Stateless public class CalculatorBean implements CalculatorRemote { public int add(int a, int b) {... 생략 public int sub(int a, int b) {... 생략 public int mul(int a, int b) {... 생략 public int div(int a, int b) {... 생략 50
Session Bean 구현클래스 Business Interface에 @Remote annotation을사용하지않고 Bean에서직접 @Remote annotation 사용가능 @Stateless @Remote(CalculatorRemote.class) public class CalculatorBean implements CalculatorRemote { public int add(int a, int b) {... 생략 public int sub(int a, int b) {... 생략 public int mul(int a, int b) {... 생략 public int div(int a, int b) {... 생략 51
Remote/Local Interface 를모두가진 Session Bean Session Bean 은 Remote/Local Interface 를모두가질수있다. 일반적으로둘중에하나만구현하는경우가많음. 52
Remote/Local Interface 를모두가진 Session Bean Session Bean 정의시 @Local/@Remote annotation 을모두 사용할수있음 @Stateless @Local(CalculatorLocal.class) @Remote(CalculatorRemote.class) public class CalculatorBean implements CalculatorRemote { public int add(int a, int b) {... 생략 public int sub(int a, int b) {... 생략 public int mul(int a, int b) {... 생략 public int div(int a, int b) {... 생략 53
Stateless Session Bean 이란? Session Bean의한종류 모든클라이언트에대해서동일하게처리됨 특정클라이언트의상태를유지하지않음 Session Bean 95% 이상차지 실제비즈니스로직을구현하는데사용 EJB Instance Pool을이용함 메소드호출시 JTA/Local Transaction이수행되며메소드호출이완료되면 Transaction이 commit됨 메소드호출시시스템수준의예외가발생하는 Transaction은 rollback됨 54
Stateless Session Bean 의인스턴스는모두동일하다 Stateless Session Bean 은 EJB Container 가 EJB Instance Pool 을이용하여사용하므로상태를유지할수없고모든클라이언트에대해서동일하게처리됨 클라이언트 A 호출 호출 1 인스턴스풀 C 빈의인스턴스 호출 2 5 3 4 클라이언트 B A 빈의인스턴스 B 빈의인스턴스 55
EJB Instance Pool EJB Container 는컨테이너가구동할때 Stateless Session Bean 의인스턴스를생성하여 EJB Instance Pool 에넣고풀링한다. 클라이언트 A 와 B 가 A 라는빈을호출할때 EJB Container 는서 로다른인스턴스를호출하게해주므로상태유지가원천적으로 불가능 클라이언트 A 호출 호출 1 호출 2 5 EJB Container 3 4 인스턴스풀 C 빈의인스턴스 클라이언트 B A 빈의인스턴스 B 빈의인스턴스 56
Stateless Session Bean 의 Life Cycle Stateless Session Bean 은매우단순한생명주기를가짐 존재하지않는상태 1. newinstance() 2. Dependency Injection 3. @PostConstruct 콜백 @PreDestory 콜백 비즈니스메소드 Method-Ready Pool 타임아웃콜백 57
Life Cycle 과 Callback EJB Container 는 Session Bean 의인스턴스의생명주기를제어 할때적절한시점에서 Callback 메소드를호출한다. Callback 메소드는컨테이너가호출하는메소드로개발자는적절하게구현해야한다. @Stateless public class MyStatelessBean implements MyStateless { private Connection conn; public MyStatelessBean() { // 기본생성자.. @PostConstruct public void dopostconstruct() { Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("mydatasource"); conn = ds.getconnection(); // 콜백메소드에서 JDBC 커넥션을얻는다.... 생략 58
Stateless Session Bean 의 Callback Stateless Session Bean 은두개의 Callback 메소드를지원 @PostConstruct 빈이생성된이후에컨테이너가호출 @PreDestroy 빈이파괴되기직전에컨테이너가호출 존재하지않는상태 1. newinstance() 2. Dependency Injection 3. @PostConstruct 콜백 @PreDestory 콜백 비즈니스메소드 Method-Ready Pool 타임아웃콜백 59
다른 EJB 빈을참조 하나의빈이다른빈을참조할때기존의EJB 2.x에서는 JNDI를이용하여직접코드를작성해야함 @Stateless public class SessionFacadeBean implements SessionFacade { OrderFacade orderfacade; public void callorderfacade() { try { Context ctx = new InitialContext(); // JDNI를통해 lookup을한다. facade = (OrderFacade) ctx.lookup("orderfacadebean/local"); orderfacade.methodsomething(); // OrderFacade 무상태세션빈을호출 catch (Exception e) { // 예외처리를한다.... 생략 60
@EJB annotation 을이용한 EJB 빈참조 EJB 3.x 에서는 @EJB annotation 을이용하여간단하게참조 @Stateless public class SessionFacadeBean implements SessionFacade { @EJB OrderFacade orderfacade; // Dependency Injection public void callorderfacade() { orderfacade.methodsomething(); // OrderFacade 무상태세션빈을호출... 생략 EJB Container 클라이언트 원격호출 리모트인터페이스 SessionFacade 로컬호출 무상태세션빈 로컬인터페이스 @EJB 를이용한레퍼런스참조 OrderFacade 무상태세션빈 TORDER 테이블 61
외부리소스를참조하는빈 외부리소스 ( 예 ; 데이터베이스 ) 를참조하려면기존의 EJB 2.x 에서 는 JNDI 를이용해야했지만 EJB 3.0 에서는 @Resource annotation 을사용한다. EJB Container 클라이언트 원격호출 리모트인터페이스 SessionFacade 무상태세션빈 @EJB 를이용한레퍼런스참조 TORDER 로컬호출 로컬인터페이스 OrderFacade 무상태세션빈 처리 테이블 @Resource 를이용한레퍼런스참조 DataSource 62
외부리소스를참조하는빈 @Resource annotation 을이용하여 JNDI 명을기술하면 EJB Container 가 DataSource 의레퍼런스를설정 @Stateless public class OrderFacadeBean implements OrderFacade { @Resource(mappedName = "java:oracleds") // dependency injection DataSource ds; public OrderPk insert(order dto) throws DAOException { Connection conn = null; PreparedStatement stmt = null; try { conn = ds.getconnection(); stmt = conn.preparestatement(sql_insert);... 생략 return dto.createpk(); catch (Exception e) { throw new DAOException(" 새로운 Order를추가할수없습니다.", e); finally {... 생략... 생략 63
Stateful Session Bean 이란? Session Bean의한종류 특정클라이언트의상태를유지함 실제업무에서거의사용하지않음 대부분의웹애플리케이션에서는특정사용자의정보를유지하는경우 HttpSession을사용함 실제비즈니스로직을구현하는데사용 EJB Instance Cache를이용함 하나의트랜잭션이여러메소드를통해전파되어처리가가능 Stateless Session Bean보다복잡한 Life Cycle을가짐 트랜잭션이롤백되는경우상태를이전으로복구시키는 Callback 메소드를제공 64
EJB Instance Cache Stateful Session Bean 은클라이언트가요청할때빈의인스턴 스를생성하며생성한빈인스턴스는 EJB Instance Cache 에보 관 65
특정클라이언트에만사용하는빈인스턴스 Stateful Session Bean 은특정한클라이언트가요청을하는순간생성됨 (Stateless Session Bean 은 EJB 컨테이너가가동될때빈인스턴스가복수개만들어져서풀링됨 ) 따라서특정클라이언트가요청한빈인스턴스는그사용자만사용할수있음 ( 예 ; 장바구니 ) 이런이유로 EJB Instance Pool 을이용하지않고 EJB Instance Cache 를이용함 Cache 에들어갈수있는최대인스턴스의수를초과하면 passivate 현상이발생 66
Stateful Session Bean 의 Life Cycle Stateful Session Bean 은상대적으로복잡한 Life Cycle 을가짐 존재하지않는상태 timeout 1. newinstance() 2. Dependency Injection 3. @PostConstruct 콜백 @PreDestory 콜백 @Remove 또는 timeout LRU 알고리즘에의한 @PrePassivate 콜백 트랜잭션을처리하는않는비즈니스메소드 Method Ready Passive 트랜잭션을처리하는비즈니스메소드 트랜잭션커밋 @PostActivate 콜백 트랜잭션롤백 afterbegin() beforecompletion() aftercompletion(true) aftercompletion(false) 트랜잭션을처리하는비즈니스메소드 Method Ready in Transaction(TX) 트랜잭션으로처리해서는안되는메소드또는서로다른트랜잭션에서수행하는메소드 에러 67
Stateful Session Bean 의 SessionSynchronization 상태유지세션빈은트랜잭션을수행전후의로직의값을원복시킬수있는세션동기화기능이있음 DB는롤백되면이전값으로되돌아가지만 Application은그렇지않음 Stateful Session Bean이 SessionSynchronization을구현하면세션동기화기능을사용할수있음 DB 작업을하던중롤백처리가되면장바구니도이전상태로되돌아간다. 68
SessionSynchronization 인터페이스 SessionSynchronization에는 3개의동기화메소드가정의되어있다. @Stateful public class ShoppingCartBean implements ShoppingCart, SessionSynchronization { public void afterbegin() throws EJBException, RemoteException { System.out.println("ShoppingCartBean.afterBegin()"); public void beforecompletion() throws EJBException, RemoteException { System.out.println("ShoppingCartBean.beforeCompletion()"); public void aftercompletion(boolean b) throws EJBException, RemoteException { System.out.println("ShoppingCartBean.afterCompletion() is " + b); 69
SessionSynchronization 인터페이스사용예 Stateful Session Bean 으로구현한장바구니 @Stateful public class ShoppingCartBean implements ShoppingCart, SessionSynchronization { public void afterbegin() throws EJBException, RemoteException { // 트랜잭션수행전에복원할값을임시로저장한다. public void beforecompletion() throws EJBException, RemoteException { // 필요한작업을구현한다. public void aftercompletion(boolean iscommit) throws EJBException, RemoteException { if(!iscommit) { // 롤백되었으므로 afterbegin() 메소드에서저장해둔이전값으로복원한다. else { // 커밋되었으므로 afterbegin() 메소드에서저장해둔이전값을삭제한다. 70
Stateful Session Bean 의 Passivation Passivation 은 Cache 의크기가작을때발생한다. 잦은 Passivation 은성능저하를유발한다. 71
다사용한 Stateful Session Bean 인스턴스는삭제하라! Stateful Session Bean 은개발자가작업이끝난후에삭제하지 않으면일정한시간동안 Cache 에존재하게되므로 Heap 이낭 비된다. 과도한요청이발생하면 Heap 부족으로인하여 Full GC 를유발 하고 JVM 이 Crash 된다. 따라서다사용한Stateful Session Bean은정상적으로삭제해야한다. 72
@Remove annotation 을이용한인스턴스삭제 @Remote annotation은 Stateful Session Bean의빈인스턴스를삭제할때사용한다. @Stateful public class ShoppingCartBean implements ShoppingCart, SessionSynchronization {... 생략 @Remove public void checkout() { // 결제처리를한다. // EJB 컨테이너는 @Remove 메소드를수행한이후에빈인스턴스를삭제한다. 73
Stateful Session Bean 의 Callback Stateful Session Bean 은 4 개의콜백메소드를지원한다. 콜백메소드 @PreDestroy @PostContruct @PrePassivate @PostActivate 설명빈인스턴스를삭제한이후에컨테이너가호출하는콜백메소드빈인스턴스가생성된직후에컨테이너가호출하는콜백메소드빈인스턴스가 passivate되어 2차저장소에저장되기전에호출하는콜백메소드 Passivate된빈인스턴스가 activate된후에호출하는콜백메소드 Stateless Session Bean 은 Passivation 과 Activation 을수행할 떄호출하는콜백메소드는지원하지않는다. 이유 : 그럴필요 가없다. 왜? 모든인스턴스가동일하니까 74
Session Bean 와 Exception 처리 EJB 말하는 Exception 의종류 Application 애플리케이션수행에있어서필요한예외. 일반적으로 Exception 을상속하여구현 System Exception 시스템의오류로인하여발생하는예외. 애플리케이션에서복구가불가능. RuntimeException 을상속한예외 EJBException RemoteException 기타등등 일반적인 Exception 의종류 Checked Exception Unchecked Exception RuntimeException 을상속한예외들 75
System Exception 은 EJB 에서쓰지마라! EJB 내부로직을수행하던도중 System Exception이발생하면 EJB Container는 현재수행중인 Transaction을롤백한다. 현재사용하던빈인스턴스를삭제한다. 현재상태가불안정하다고판단한다. 개발자가비즈니스로직을처리하는데있어서 System Exception을던지고제대로처리하지못하면 EJB Container는빈인스턴스를삭제하게되는데동시 Active User와비례하여인스턴스의수가모자라면다시생성하게된다. 반복적으로 create/remove 가발생하면성능에좋지않다!! 76
Summary EJB 3.0 의 Session Bean 은 POJO 기반이다. Session Bean 은 Remote/Local Interface 를모두가질수있다. Stateless Session Bean 은모든클라이언트에게동일하며 EJB Instance Pool 을사용한다. 단일메소드당하나의트랜잭션이수행되며중첩트랜잭션을지원하지않는다. Stateful Session Bean 은특정사용자의상태를유지하는빈으로써 EJB Instance Cache 를이용한다. 여러메소드를하나의트랜잭션으로수행할수있으며중첩트랜잭션은지원하지않는다. Stateful Session Bean 은세션동기화기능을제공한다. 애플리케이션예외처리는 System Exception 을사용하지마라! 77
Q & A Q & A 78
EJB 3.0 Message-Driven Bean Java EE 5.0 Business Tier Component Technology 김병곤 fharenheit@j2eearchitect.net / @gmail.com
JMS(Java Message Service) Java EE 에서유일하게비동기처리방식으로처리 1:1, 1:N 메시지송수신을지원 Message Queue 의자바표준 EJB 의 Message-Driven Bean 은 JMS 의메시지수신클라이언트 역할로수행 송신자는 JMS 의 Queue/Topic 으로메시지를비동기로송신하 고수신자는비동기로메시지를수신 80
비동기메시징의두가지방식 Point-To-Point(1:1) Messaging Publish/Subscribe(1:N) Messaging 81
Java EE 5 에서 JMS 위치 82
Message-Driven Bean Enterprise JavaBeans 를구성하고있는 Enterprise Bean 의하 나 비동기로메시지를수신하여처리하는 Enterprise Bean 비동기처리시매우유용한빈 JMS(Java Message Service) 의메시지수신클라이언트 트랜잭션처리지원 83
JMS 아키텍처와구성요소 JMS Provider 메시지송수신의책임을지는 JMS 서버제공자 ( 벤더 ;IBM, BEA..) JMS Client 메시지를송신및수신하는클라이언트 JMS Message JMS 클라이언트간송수신할수있는메시지 Administrated Object 시스템관리자의관리대상이되는객체 메시지의송수신책임을가지는 Queue/Topic 및 ConnectionFactory가여기에해당 시스템관리자가필요에따라관리콘솔에서추가가능 84
JMS 애플리케이션의구조 JMS 클라이언트는 JMS Server 를통해서비동기로메시지를송 수신 85
JMS API JMS API 를구성하는핵심인터페이스및클래스 JMS Parent PTP 메시징모델 Pub/Sub 메시징모델 ConnectionFactory QueueConnectionFactory TopicConnectionFactory Connection QueueConnection TopicConnection Destination Queue Topic Session QueueSession TopicSession MessageProducer QueueSender TopicPublisher MessageConsumer QueueReceiver, QueueBrowser TopicSubscriber 86
JMS 애플리케이션의송수신처리흐름도 JNDI 네이밍 1. lookup Destination (Queue/Topic) 2. lookup 3. 커넥션획득 ConnectionFactory Connection MessageConsumer 6. 메시지소비자생성 Session Message MessageProducer 87
JMS Administrated Object 관리 WAS 또는 JMS Server 콘솔에서는 Administrated Object를동적으로구성할수있는기능을제공 88
JMS 에서지원하는 Message 의종류 JMS 는 5 가지유형의메시지를지원 89
기타 JMS 의기능 메시지영속성 송신한메시지를 persistence storage에저장하는방식으로써메시지의안전한전달을위한기능 메시지승인 수신자가메시지를수신했는지확인하기위한 mechanism 트랜잭션처리 Java EE 의 JTA 와통합하여글로벌트랜잭션수행가능 메시지선택자 메시지의헤더의특정조건에부합하는메시지만선택적으로수신 기타등등 벤더에따라서 JMS Server 는매우다양한기능을제공함 90
Message-Driven Bean Message-Driven Bean 은 JMS 클라이언트를 Enterprise Bean 으로확장한개념 EJB Container JMS 메시지송신자 메시지송신 호출 세션빈 호출 사용 세션빈 엔티티빈 원격호출 데이터베이스처리 데이터베이스처리 웹서비스 메시지송신 메시지드리븐빈 데이터베이스처리 데이터베이스 JMS Queue 91
Message-Driven Bean 의 Life Cycle Message-Driven Bean 은 Stateless Sesssion Bean 과아주유사 한 Life Cycle 을가진다. JMS 메시지송신자 메시지송신 EJB Container 인스턴스풀 메시지드리븐빈 C 의인스턴스 M1 M3 M2 M1 M3 M2 메시지송신 JMS Queue 메시지드리븐빈 A 의인스턴스 메시지드리븐빈 B 의인스턴스 92
Message-Driven Bean 의제약사항 외부에서접근가능한인터페이스가없다. Session Bean 의경우 Remote/Local Interface 가존재 메시지수신시예외가발생하면메시지수신처리가롤백된다. 93
Message-Driven Bean 의정의 Message-Driven Bean 은다음의조건에만족하도록정의 MessageListener 인터페이스를구현 메시지수신시호출되는메소드인 onmessage() 메소드가정의 @MessageDriven annotation @MessageDriven(activationConfig = { @ActivationConfigProperty( propertyname = "destinationtype", propertyvalue = "javax.jms.topic"), @ActivationConfigProperty( propertyname = "destination", propertyvalue = "topic/testtopic")) public class MyMessageDrivenBean implements MessageListener { public void onmessage(message msg) {... 생략 94
Message-Driven Bean 의 Callback Message-Driven Bean 은 Stateless Session Bean 과매우유사 Callback도동일 Life Cycle도동일 EJB Instance Pool을사용하는것도동일 Message-Driven Bean 은 2 개의 Callback 을지원 @PostConstruct @PreDestroy 95
MessageListener 의 onmessage() 메소드 JMS 의 Queue/Topic 으로부터메시지를수신하게되면 EJB Container 가 onmessage() 메소드를호출 public void onmessage(message msg) { TextMessage m = (TextMessage) msg; try { System.out.println(m.getText()); catch (JMSException e) { // 메시지처리도중예외발생. e.printstacktrace(); 96
Summary Message-Driven Bean 은비동기처리에매우유용한빈이다. Stateless Session Bean 과 Life Cycle 이동일하다. 표준송수신메시지는 5 가지를제공한다. JTA 와같은분산트랜잭션과통합하여메시지처리가가능하다. Core J2EE Pattern 에서는이빈을이용하여다양한비동기처리 패턴을적용한다. 97
Q & A Q & A 98
EJB 3.0 Interceptor Java EE 5.0 Business Tier Component Technology 김병곤 fharenheit@j2eearchitect.net / @gmail.com
Interceptor EJB 3.0 에서새로추가된기능 특정한기능이수행되기전에먼저처리해야할작업을기술하여수행하는기능 AOP(Aspect-Oriented Programming) 의 Advice 와유사 특정메소드, 특정클래스에대해서 Interceptor 를적용가능 100
Interceptor 의호출 클라이언트가비즈니스로직을호출하면 EJB Container 는비즈 니스로직을호출하기전에 Interceptor 를먼저처리한다. 101
Interceptor 의유형 2 가지유형의 Interceptor Interceptor 유형 정의방법 Annotation 장단점 Interceptor 메소드 빈구현코드내부에정의 @AroundInvoke 사용하기쉽지만빈내부코드가지저분해진다. Interceptor 클래스 별도의클래스로구현 @Interceptors @Interceptor 완전히빈코드와분리시킬수있다. 102
Interceptor Method Interceptor Method 은 @AroundInvoke annotation 으로정의 @Stateless public class InterceptorHelloBean implements InterceptorHello { public void sayhello() { System.out.println("Hello EJB 3.0~!"); @AroundInvoke public Object myinterceptor(invocationcontext ctx) throws Exception { System.out.println("Interceptor가호출되었습니다."); // 계속 HelloWorldBean의비즈니스메소드를실행합니다. return ctx.proceed(); 처리결과 11:08:45,265 INFO [STDOUT] Interceptor가호출되었습니다. 11:08:45,265 INFO [STDOUT] Hello EJB 3.0~! 103
Interceptor Class 개별클래스의특정메소드에 @AroundInvoke annotation 으로 기술 public class TracingInterceptor { @AroundInvoke public Object log(invocationcontext ctx) throws Exception { System.out.println("TracingInterceptor가호출되었습니다."); long start = System.currentTimeMillis(); // 시작시간을측정한다. try { return ctx.proceed(); // 비즈니스메소드를호출한다. catch (Exception e) { throw e; finally { // 비즈니스메소드가호출되고나면이메소드가호출된다. long time = System.currentTimeMillis() - start; String method = ctx.getbean().getclass().getname() + "." + ctx.getmethod().getname() + "()"; System.out.println(method + " 메소드의수행성능은 " + time + "ms초"); 104
Interceptor Class Enterprise Bean은 @Interceptors annotation을이용하여하나이상중복하여interceptor Class를정의 @Stateless @Interceptors(TracingInterceptor.class) public class JMSSenderBean implements JMSSender { @Resource(mappedName = "queue/testqueue", type = javax.jms.queue.class) Queue queue;... 생략 105
Method 수준의 Interceptor Class Interceptor Class 를특정메소드에게만적용가능 @Stateless public class MethodLevelInterceptorBean implements InterceptorHello { @Interceptors(TracingInterceptor.class) public void sayhello() { System.out.println("Hello EJB 3.0~!"); 106
복잡한 Interceptor 의정의 하나이상의 Interceptor 를다양하게적용할수도있음 @Stateless @Interceptors(OtherInterceptor.class) public class MethodLevelInterceptorBean implements InterceptorHello { @ExcludeClassInterceptors @Interceptors(TracingInterceptor.class) public void sayhello() { System.out.println("Hello EJB 3.0~!"); 107
InvocationContext 인터페이스 메소드명 설명 getbean() 빈의인스턴스를반환한다. getmethod() interceptor 가호출하는빈의메소드를반환한다. @AroundInvoke annotation 에서는호출하는빈의메소드가반환되지만 callback interceptor 메소드의경우는 null 을반환한다. getparameters() 메소드의파라미터가반환된다. setparameters() 메소드의파라미터를설정한다. getcontextdata() InvocationContext 에서전달할값을반환한다. 이메소드의반환값이 Map 을이용하면다수의 interceptor 간에정보를서로전달할수있다. proceed() 하나이상의 interceptor 를호출하도록되어있다면다음 interceptor 를호출한다. 그리고맨마지막 interceptor 가호출되면 EJB 의비즈니스메소드를호출한다. 하나이상의 interceptor 를호출하도록되어있다면컨테이너가각각의 interceptor 를호출이완료될때마다호출하며이 proceed() 메소드의반환값은호출된다음메소드의결과값이다. 만약에메소드의반환값이 void 라면이반환값도 null 이된다. 이전에 sayhello() 메소드가처리되고난후 proceed() 메소드가 null 을반환한것은 sayhello() 메소드의반환값이 void 이기때문이다. 108
Life Cycle Callback Interceptor Enterprise Bean 의 Life Cycle 에대한 Callback 메소드를컨테 이너가호출하기전에 Interceptor 를사용할수있다. public class LifecycleInterceptor { @PostConstruct // @PostConstruct 콜백메소드를호출하기전호출된다. public void postconstruct(invocationcontext ctx) { try { System.out.println("LifecycleInterceptor postconstruct called"); ctx.proceed(); catch (Exception e) { throw new RuntimeException(e); finally { System.out.println("LifecycleInterceptor postconstruct end"); 109
Life Cycle Callback Interceptor Callback 메소드가호출되기전에 Callback 메소드에대한 Interceptor를정의한다. @Stateless @Interceptors(LifecycleInterceptor.class) // Callback Interceptor를정의. public class LifecycleCallbackBean implements LifecycleCallback {... 생략 @PostConstruct // Callback public void dopostconstruct() { System.out.println("doPostConstruct() called"); 110
Summary Interceptor는특정로직이수행되기전에수행하는공통로직을정의할때사용 Interceptor는초보적인 AOP의개념 Interceptor Method/Class를제공 Interceptor Class는전체빈의메소드가모두적용됨 Interceptor Method와 Class를혼합하여적용가능 Life Cycle Callback도 Interceptor를적용할수있음 111
Q & A Q & A 112
EJB 3.0 Transaction & Exception Java EE 5.0 Business Tier Component Technology 김병곤 fharenheit@j2eearchitect.net / @gmail.com
EJB Transaction 과 Exception EJB 에서 Transaction 과 Exception 은매우밀접한관계가있음 EJB Transaction 은 Local Transaction 및 JTA Transaction 을모두지원 개발자는 Transaction 에대해서선언또는프로그래밍기법적용가능 EJB 는기본적으로메소드호출에대해서단일트랜잭션으로수행 시스템예외는트랜잭션을롤백시킴 114
EJB Transaction Scenario - 1 동일서버내에서여러데이터베이스의값을변경 115
EJB Transaction Scenario - 2 동일서버내에서 JMS 의 Queue 와다수의데이터베이스값을 변경 116
EJB Transaction Scenario - 3 메시지를수신하는메시지드리븐빈이다수의데이터베이스의값을변경 117
EJB Transaction Scenario - 4 여러 EJB 서버에서데이터베이스의값을변경 EJB Container EJB Container Client X Y 데이터베이스 A 데이터베이스 B 118
EJB Transaction Scenario - 5 클라이언트소스코드내에서트랜잭션을시작하며관리 begin 데이터베이스 A commit 데이터베이스 B 119
EJB Transaction Scenario - 5 클라이언트소스코드내에서트랜잭션을시작하며관리 클라이언트는 UserTransaction을 JNDI를통해얻어서클라이언트에서트랜잭션을수행 Context ctx = new InitialContext(); tx = (UserTransaction)ctx.lookup( java:comp/env/usertransaction"); tx.begin(); // 트랜잭션시작 bean.deposit(100); // 엔터프라이즈빈호출. tx.commit(); 또는 tx.rollback(); // 트랜잭션종료 120
EJB Transaction Scenario - 6 자바가아닌클라이언트또는서버와의호환성 121
EJB Transaction 유형별분류 트랜잭션관리방법에따른분류 컨테이너가트랜잭션을관리 (Container-Managed Transaction;CMT) 선언적트랜잭션 ( 트랜잭션의수행방법을선언하면 EJB Container 가수행하는방식 ) 개발자가트랜잭션을관리 (Bean-Managed Transaction;BMT) 개발자가직접코드를작성하여트랜잭션을수행하는방식 EJB Specification 에서는 CMT 를권장 CMT 는 BMT 보다간결하며사용하기쉽고분산트랜잭션처리를 EJB Container 가처리하도록위임하는방식. 122
Container-Managed Transaction 클라이언트가 Enterprise Bean 의특정메소드를호출하면 EJB Container 가트랜잭션을알아서 begin/commit/rollback 123
Bean-Managed Transaction 개발자는 Enterprise Bean 코드에직접트랜잭션관리코드를추가하여트랜잭션을관리 UserTransaction tx = ejbcontext.getusertransaction(); try { tx.begin(); // 트랜잭션시작 deposit(100); // 엔터프라이즈빈호출, 여러메소드가들어올수있다. tx.commit(); // 트랜잭션커밋 catch (Exception ex) { try { tx.rollback(); // 예외발생시트랜잭션롤백. BMT에서만사용하는메소드. catch (SystemException syex) { throw new EJBException(" 롤백실패 : " + syex.getmessage()); throw new EJBException (" 트랜잭션실패 : " + ex.getmessage()); 124
Transaction Attributes EJB Container 는다양한트랜잭션속성을지원 트랜잭션속성 REQUIRED REQUIRES_NEW SUPPORTS NOT_SUPPORTED MANDATORY NEVER 설명 기본트랜잭션속성 무조건트랜잭션처리 빈메소드를호출하면항상새로운트랜잭션으로처리 트랜잭션지원을명시 이미트랜잭션이시작된상황에서이메소드를호출하면계속처리 트랜잭션이시작되지않은상황에서이메소드를호출하면그래도계속처리 트랜잭션을지원한다는의미 트랜잭션을지원하지않음을명시 트랜잭션이시작된상황에서이속성으로명시된빈메소드를호출하면트랜잭션이일시중지됨 반드시트랜잭션으로처리함을명시 특정메소드가이속성을되어있지만트랜잭션처리가되지않으면예외발생 절대로트랜잭션으로처리해서는안됨을명시 트랜잭션이시작된상황에서이메소드를호출하면예외발생 125
Transaction 속성과트랜잭션전파 하나이상의빈메소드는다양한트랜잭션속성을가질수있음 하나의빈메소드는여러빈의메소드를호출할수있음 여러트랜잭션속성이결합할때트랜잭션의전파는서로다른형태로이루어짐 126
Transaction Attribute NOT_SUPPORTED 트랜잭션을지원하지않는것을의미하며트랜잭션이시작된상태에서이속성을가진메소드를호출하면트랜잭션은일시중지 트랜잭션속성클라이언트트랜잭션비즈니스메소드리소스관리자 NOT_SUPPORTED 없음없음없음 T1 없음없음 ** 리소스관리자는데이터베이스를의미 127
Transaction Attribute REQUIRED 트랜잭션을지원한다는것을의미하며기본값 트랜잭션이없다면트랜잭션을새로시작하여메소드를처리 트랜잭션속성클라이언트트랜잭션비즈니스메소드리소스관리자 REQUIRED 없음 T2 T2 T1 T1 T1 ** 리소스관리자는데이터베이스를의미 128
Transaction Attribute SUPPORTS 트랜잭션을지원한다는것을의미 트랜잭션이없으면없는대로, 있으면있는대로처리 트랜잭션속성클라이언트트랜잭션비즈니스메소드리소스관리자 SUPPORTS 없음없음없음 T1 T1 T1 ** 리소스관리자는데이터베이스를의미 129
Transaction Attribute REQUIRES_NEW 트랜잭션을지원하지만새로시작해야함을의미 이미트랜잭션이시작되어있더라도무조건새로트랜잭션을시작 트랜잭션속성클라이언트트랜잭션비즈니스메소드리소스관리자 REQUIRES_NEW 없음 T2 T2 T1 T2 T2 ** 리소스관리자는데이터베이스를의미 130
Transaction Attribute NOT_SUPPORTED 트랜잭션을지원하지않는것을의미하며트랜잭션이시작된상태에서이속성을가진메소드를호출하면트랜잭션은일시중지 트랜잭션속성클라이언트트랜잭션비즈니스메소드리소스관리자 NOT_SUPPORTED 없음없음없음 T1 없음없음 ** 리소스관리자는데이터베이스를의미 131
Transaction Attribute MADATORY 반드시트랜잭션으로처리해야함을의미 트랜잭션처리를하지않으면예외발생 트랜잭션속성클라이언트트랜잭션비즈니스메소드리소스관리자 NOT_SUPPORTED 없음에러 N/A T1 T1 T1 ** 리소스관리자는데이터베이스를의미 132
Transaction Attribute NEVER 절대로트랜잭션으로처리해서는안됨 트랜잭션으로처리하면예외발생 트랜잭션속성클라이언트트랜잭션비즈니스메소드리소스관리자 NOT_SUPPORTED 없음 없음 없음 T1 에러 N/A ** 리소스관리자는데이터베이스를의미 133
빈의트랜잭션관리속성지정하기 @TransactionManagement annotation을이용하여cmt인지 BMT인지를결정 @Stateless @TransactionManagement(TransactionManagementType.BEAN) // BMT로지정 public class BMTBean implements BMT { @ResourceSessionContext ctx;... 생략 134
빈메소드의트랜잭션속성정의하기 CMT에서다음과같이 @TransactionAttribute annotatio으로트랜잭션속성을정의 @TransactionAttribute(TransactionAttributeType.REQUIRED) public void addbook(book book) throws CMTException { Connection conn = null; PreparedStatement psmt = null; try { conn = ds.getconnection(); String sql = "INSERT INTO BOOK (...) VALUES(...)";... 생략 catch (Exception e) { ctx.setrollbackonly(); // 트랜잭션을롤백한다. CMT에서만지원 throw new CMTException(" 예외가발생했습니다.", e); finally { // 관련자원을해제한다. close(psmt, conn); 135
EJB Exception EJB Exception 처리는 EJB Specification 에서많은양을할당할 만큼중요 대부분의개발자들이 EJB Exception 에대해서이해가없는경우 가많음 EJB Exception 은트랜잭션처리와밀접한관계를가짐 Exception 에따라 EJB Container 의트랜잭션처리의방식이달 라짐 136
Exception 의구조 137
EJB Exception 의분류 Application Exception Exception 을상속한예외 비즈니스애플리케이션에서사용하는예외 이예외가발생하더라도트랜잭션은롤백되지않음 System Exception RuntimeException 을상속한예외 시스템에서는복구할수없는수준의예외라고판단 EJB Bean Instance 를삭제 트랜잭션을롤백 대표적으로다음의예외가있음 NullPointerException, EJBException, RemoteException, ClassCastException, 기타등등 ** RemoteException 은 RuntimeException 을상속하지않았지만시스템예외로간주 138
Application Exception 정의하기 비즈니스로직과관련된예외는 Application Exception 을사용 해야함 Exception 을상속한예외가되어야함 @Application annotation은해당예외가application Exception임을명시 @ApplicationException(rollback = true) Public class MyApplicationException extends Exception {... 생략 Application Exception는명시적으로트랜잭션이롤백되지않기때문에개발자가 rollback=true 로설정하여명시적으로롤백하도록설정가능 139
CMT 환경에서명시적으로트랜잭션롤백처리 CMT 는 EJB Container 가트랜잭션을모두관리 하지만개발자는명시적으로처리하고싶은경우도있음 CMT 환경에서명시적으로트랜잭션을롤백하려면 EJBContext.setRollbackOnly() 메소드를호출하던가 EJBException을던지던가 @ApplicationException(rollback=true) 로설정하던가 140
System Exception 의제약사항 System Exception 은 RuntimeException을상속한예외 RemoteException System Exception은 try-catch 로처리하기곤란. 개발자는 System Exception을 try-catch로처리해서는안됨 System Exception은 EJB Container가처리하도록위임 System Exception이발생하면EJB Bean Instance가삭제되고트랜잭션이롤백 System Exception이빈번하게발생하면EJB Bean Instance가생성되고삭제되는과정이빈번하게이루어져컨테이너에부담이됨 141
Summary EJB Container는분산된환경에서도동일한방식으로 Transaction처리를유연하게처리 개발자는 CMT를사용한것을강력히권고 Transaction의시작에따라서코딩하는방식이다름 EJB Specification에서는 Exception 처리를강력히 recommend하고있음 비즈니스로직의처리는 Application Exception만사용해야함 System Exception은트랜잭션이롤백되고 EJB Bean Instance 가삭제됨 142
Q & A Q & A 143
EJB 3.0 Timer Service Java EE 5.0 Business Tier Component Technology 김병곤 fharenheit@j2eearchitect.net / @gmail.com
Timer Service 특정시간또는특정한주기동안비즈니스로직을수행해야할일이발생하는경우사용하는서비스 EJB 2.1 에서새로추가 자바의 java.util.timer 와유사 EJB 컨테이너내부에서동작하는타이머 트랜잭션지원 145
Java 의 java.util.timer 타이머 Java SE 환경에서는 Timer와 TimerTask를이용하여타이머기능을구현할수있음 int numberofmillisecondsinthefuture = 10000; // 10초 Date timetorun = new Date(System.currentTimeMillis() + numberofmillisecondsinthefuture); Timer timer = new Timer(); // 타이머생성 timer.schedule(new TimerTask() { // 타이머가실행할 TimerTask를구현 public void run() { // 10초후에해야할작업을정의, timetorun); // 타이머스케줄링 146
java.util.timer 의한계 복잡한스케줄링을지원하지않음 단일쓰레드기반 EJB 컨테이너내부에서사용하는데위험이따름 (EJB 에서는 Thread 를직접컨트롤하지않도록하고있음 ) 147
EJB 의 Timer Service 에서제공하는 Timer Timer createtimer(long duration, java.io.serializable info) 일정한시간이후에타이머이벤트를발생하는타이머를생성한다. Timer createtimer(long initalduration, long intervalduration, java.io.serializable info) 초기대기시간이후에반복적으로대기하면서이벤트를발생하는타이머를생성한다. Timer createtimer(java.util.date expiration, java.io.serializable info) 타이머의기한만료시간까지수행하는타이머를생성한다. Timer createtimer(java.util.date initialexpiration, long intervalduration, java.io.serializable info) 초기 expire 이후에반복적으로대기하면서이벤트를발생하는타이머를생성한다. Collection gettimers() 타이머서비스에등록되어있는모든타이머를반환한다. 10초간대기한이후에 5초마다수행하는타이머 Timer timer = TimerService.createTimer(10000, 2000, "Hello World"); 148
EJB Timer 서비스얻기 EJB Timer 서비스는다음의경우중에한가지방법으로얻을수있다. Dependency Injection JNDI EJBContext.getTimerService() 149
Dependency Injection 을이용한 Timer Service 얻기 @Resource annotation 을이용하여 Timer Service 를얻는다. @Stateless public class SimpleTimer implements SimpleTimerRemote { @Resource private javax.ejb.timerservice timer; // Dependency Injection public void calltimer(long milliseconds) { timer.createtimer(new Date(new Date().getTime() + milliseconds), "Hello World");... 생략 150
EJBContext 를이용한 Timer Service 얻기 EJBContext 를이용하여 Timer Service 를얻는다. @Stateless public class SimpleTimer implements SimpleTimerRemote { @Resource private SessionContext ctx; // Dependency Injection public void calltimer(long milli) { ctx.gettimerservice().createtimer(new Date(new Date().getTime() + milli), "Hello World");... 생략 151
JNDI 를이용한 Timer Service 얻기 JNDI 에등록되어있는 Timer Service 를얻는다. Context ctx = new InitialContext(); TimerService timer = (TimerService) ctx.lookup("mytimer"); timer.createtimer(new Date(new Date().getTime() + milliseconds), "Hello World"); 152
Timeout Callback @Timeout annotation 은타이머서비스가해당시간이되었을 때발생하는 Callback 을지정할때사용 Timer 가 expire 되면이 @Timeout Callback 메소드를호출 @Timeout public void timeouthandler(timer timer) { System.out.println("-----------------------------------"); System.out.println(" 타이머이벤트발생 : " + timer.getinfo()); System.out.println("-----------------------------------"); timer.cancel(); 153
Timer 가적용된 Stateless Session Bean 예제 @Stateless public class SimpleTimer implements SimpleTimerRemote { @Resource private javax.ejb.timerservice timer; // Dependency Injection public void calltimer(long milliseconds) { timer.createtimer(new Date(new Date().getTime() + milliseconds), "Hello"); @Timeout public void timeouthandler(timer timer) { System.out.println("-----------------------------------"); System.out.println(" 타이머이벤트발생 : " + timer.getinfo()); System.out.println("-----------------------------------"); timer.cancel(); 154
Timer Service 와 Exception 그리고 Transaction 타이머가스케줄링되어있을때 System Exception 을발생하면 EJB Instance 는삭제된다. 또한타이머도삭제된다. 타이머를취소할때트랜잭션이롤백되면타이머취소자체도롤백된다. 타이머를생성할때트랜잭션이롤백되면타이머생성자체도롤백된다. 155
Timeout Callback 과 Life Cycle Timeout 이발생한이후에는 Stateless Session Bean 은다시 EJB Instance Pool 로복귀한다. 존재하지않는상태 1. newinstance() 2. Dependency Injection 3. @PostConstruct 콜백 @PreDestory 콜백 비즈니스메소드 Method-Ready Pool 타임아웃콜백 156
TimerHandler TimerHandler는 Timer Service를직렬화하여보관할수있는기능을제공한다. 직렬화를통해파일에기록했다가다시 Timer Service를재사용할수있다. 실제로쓸일이없는기능!! 157
Summary EJB Timer Service 는간단한스케줄링기능을제공한다. 트랜잭션과연관지어처리할수있다. 다양한방식으로 Timer Service 를얻을수있다. 보다정교한 Timer Service를사용하려면엔터프라이즈스케줄러인 OpenSymphony의 Quartz Job Scheduler가좋은대한 Spring Framework과잘통합되므로 Java EE 애플리케이션에서쉽게사용할수있다. WAS와어댑터를제공한다. 158
Q & A Q & A 159
EJB 3.0 WebService Java EE 5.0 Business Tier Component Technology 김병곤 fharenheit@j2eearchitect.net / @gmail.com
EJB WebService EJB 2.1 에서추가된기능 EJB 의비즈니스로직을웹서비스로 export 하여타플랫폼에서 호출할수있게함 EJB 3.0 은보다간결하게웹서비스를구성할수있음 Session Bean 을 WebService 가가능하도록하면 WSDL 을 EJB Container 가자동생성하고 export 함 161
EJB WebService Interface 정의 WebService로 export할인터페이스는 @WebService와 @SOAPBinding annotation을이용하여기술 인터페이스는 Remote 인터페이스를상속해야함 @WebService @SOAPBinding(style = SOAPBinding.Style.RPC) public interface EndpointInterface extends Remote { String sayhello(); // WebService 로 export 할메소드 162
EJB WebService Bean Implementation WebService의 Endpoint Interface를정의하고 WebService로 export할메소드를 @WebMethod annotation 으로기술 @Stateless @WebService(endpointInterface = "com.j2eearchitect.ejb3.webservice.endpointinterface") @Remote(EndpointInterface.class) // 리모트인터페이스 public class MyWebService { @WebMethod public String sayhello() { // 웹서비스를통해원격에서호출할메소드 return " 나의이름은팬돌이."; 163
EJB WebService Deploy Stateless Session Bean 을 WebService 가가능하도록하여배 포하면 EJB Container 는동적으로 WSDL 을구성 [WSDLFilePublisher.java] WSDL published to: file:/c:/program Files/JBoss- 4.0.5.GA/server/default/data/wsdl/tutorial.jar/EndpointInterfaceService2 7040.wsdl [ServiceEndpointManager.java] WebService started: http://onyx:8080/tutorial/mywebservice 웹브라우저에서는 http://<ip>:8080/<deploy_file>/mywebservice?wsdl 을통해서 WSDL에접근가능 164
WebService WSDL 파일 165
WebService Client.NET 기반플랫폼에서는.NET Framework SDK 의 wsdl.exe 를통 해서 WSDL 을분석하여호출가능한코드를자동생성 Java 기반플랫폼에서는 WebService Client 를별도로구성 JBoss의경우클라이언트는 CLASSPATH의 META-INF/standardjaxrpc-client-config.xml 파일을포함시켜야함 타 Web Application Server(WAS) 의경우는다소상이함 166
Java 기반 WebService Client 작성하기 public class Client { public static void main(string[] args) throws Exception { String serviceurl = "http://localhost:8080/tutorial/mywebservice?wsdl"; URL url = new URL(serviceUrl); String namespace = "http://webservice.ejb3.j2eearchitect.com/jaws"; String servicename = "EndpointInterfaceService"; QName qname = new QName(namespace, servicename); ServiceFactory factory = ServiceFactory.newInstance(); Service remote = factory.createservice(url, qname); EndpointInterface proxy = (EndpointInterface) remote.getport(endpointinterface.class); 공통코드 // 웹서비스를이용한비즈니스로직호출 System.out.println(" 웹서비스호출결과 : " + proxy.sayhello()); 167
Summary EJB WebService 는 Enterprise Bean 을매우손쉽게 WebService 를할수있도록구성 EJB Container 는 WebService 가가능한빈의인터페이스를 WSDL 로 export 함 타플랫폼 (.NET/Java/ 기타등등 ) 에서는이 WSDL 을이용하여플 랫폼을통합할수있음 168
Q & A Q & A 169
EJB 3.0 Development Java EE 5.0 Business Tier Component Technology 김병곤 fharenheit@j2eearchitect.net / @gmail.com
EJB 3.0 기반애플리케이션개발환경요구사항 Java Development Kit(JDK) Sun JDK 5.0 이상 Integrated Development Environment(IDE) Eclipse 3.2 이상 IntelliJ IDEA 6.x 이상 Borland JBuilder 2006 이상 NetBeans 5.5 JDeveloper 최신 Web Application Server(WAS) JBoss 4.0.5GA GlassFish BEA WebLogic 10 Oracle AS Tmax JEUS 6.0 Preview 기타등등. 171
WAS 의 Entity Bean(JPA) 구현메커니즘 JBoss 4.0.5GA Hibernate BEA WebLogic 10 Solarmetrics Kodo JDO Oracle AS Oracle Toplink Essential Tmax JEUS 6.0 Preview Oracle Toplink Essential 172
Application Deployment EAR.ear 파일 웹애플리케이션이있는경우 EJB로구현된애플리케이션이있는경우 웹애플리케이션이 EJB를호출해야하는경우.ear 파일은다수의 EJB.jar와.war 파일로구성됨 EJB.jar 파일 웹애플리케이션이없는경우 EJB 로만구성되는 EJB 애플리케이션의경우에는 EJB.jar 파일형 태로배포가능 173
Enterprise Application EAR.ear 패키징 J2EE Server( 웹애플리케이션서버 ) JNDI Naming Service 웹서비스 Connector Web Container 리소스검색 호출 EJB Container 세션빈 원격호출 외부서버 요청 JSPs 세션빈 사용 데이터베이스처리 클라이언트 웹서버 Servlet Servlet 호출 메일송신 메시지송신 메시지드리븐빈 엔티티빈 데이터베이스처리 데이터베이스처리 데이터베이스.war 패키징 Java Mail.jar 패키징 Java Message Service 메시지송신.ear 패키징 174
JBoss 의 EAR.ear 파일의구조.ear 파일 META-INF application.xml jboss-app.xml.war 와.jar 를정의한 XML 파일.war 파일 WEB-INF lib classes web.xml jboss-web.xml intro.jsp search.jsp 웹애플리케이션관련 XML 파일.jar 파일 META-INF com persistence.xml Persistence Unit 을정의한 XML 파일 j2eearchitect ejb3 entity 엔티티빈클래스 FacadeSession Address.class Customer.class Shop.class Menu.class OrderMenu.class Payment.class... 175
EAR.ear 의 application.xml 파일 EAR.ear 파일을구성하는 EJB와웹애플리케이션등에대한아카이브파일에대한정의가포함 <?xml version="1.0" encoding="utf-8"?> <application> <display-name>ejb3trail</display-name> <description>j2ee Made Easy Trail Map</description> <module> <ejb>beans.jar</ejb> </module> <module> <web> <web-uri>web.war</web-uri> <context-root>ejb3trail</context-root> </web> </module> </application> 176
JBoss 의특정파일은 jboss-app.xml JBoss 에서만사용하는 Application Description XML 파일 <jboss-app> <loader-repository> trailblazer:app=ejb3 </loader-repository> </jboss-app> EAR.ear 파일은 jboss-app.xml 파일의내용이모두달라야함 jboss-app.xml 파일은해당 EAR.ear 파일의클래스가다른애플리케이션과충돌을방지하기위해서 ClassLoader를완전하게격리시키기위해서사용하는파일 177
EJB.jar 의 Entity Bean 설정파일인 persistence.xml EJB 3.0의 Entity Bean은 Persistence Provider를통해동작가능하게됨 이 Persistence Provider와 Entity Bean에대한정의는 persistence.xml 파일에기술 <persistence version="1.0"> <!-- Persistence Unit을정의하고트랜잭션의유형을결정 --> <persistence-unit name="manager" transaction-type="resource_local"> <provider>org.hibernate.ejb.hibernatepersistence</provider> <!-- Oracle DataSource에대한 JNDI 이름설정 --> <jta-data-source>java:/oracleds</jta-data-source> <properties> <!-- JBoss의 EJB 3.0 JPA 구현체인 Hibernate 설정속성 --> <property name="hibernate.show_sql" value="true"/> <property name="org.hibernate.hbm2ddl" value="update"/> </properties> </persistence-unit> </persistence> 178
JNDI Naming 규칙 Stateless Session Bean 이다음과같은경우 Remote Interface : com.xx.xx.helloremote Local Interface : com.xx.xx.hellolocal Bean Class : com.xx.xx.hellpbean JNDI 명은패키징과호출방식에따라서다음과같이결정됨 EAR.ear Remote Call : <EAR_FILE_NAME>/HelloRemote/remote Local Call : <EAR_FILE_NAME>/HelloLocal/local EJB.jar Remote Call : HelloRemote/remote Local Call : HelloLocal/local 179
JNDI Naming 규칙사용예 EAR.ear 패키징을하고 JSP 페이지에서 EJB 를호출하는경우 InitialContext ctx = new InitialContext(); Calculator cal = (Calculator) ctx.lookup("ejb3trail/entitycalculator/local"); EAR.jar 파일로배포하고 EJB 가다른 EJB 를호출하는경우 (Dependency Injection 사용하지않음 )(Local 호출 ) InitialContext ctx = new InitialContext(); Calculator cal = (Calculator) ctx.lookup("entitycalculator/local"); EAR.jar 파일로배포하고원격클라이언트가호출하는경우 (Remote 호출 ) InitialContext ctx = new InitialContext(); Calculator cal = (Calculator) ctx.lookup("entitycalculator/remote"); 180
Q & A Q & A 181