EJB 컨테이너
1. 개요
1. 개요
EJB 컨테이너는 엔터프라이즈 애플리케이션의 핵심 비즈니스 로직을 구현하는 EJB 컴포넌트의 실행 환경이다. 이 컨테이너는 빈의 생성과 소멸을 포함한 생명주기를 전적으로 관리하며, 개발자가 직접 처리하기 복잡한 트랜잭션 관리, 보안, 동시성 제어 등의 시스템 수준 서비스를 투명하게 제공한다. 이를 통해 애플리케이션 개발자는 순수한 비즈니스 로직 구현에 집중할 수 있도록 한다.
썬 마이크로시스템즈에 의해 1998년 J2EE 플랫폼의 일부로 최초 등장한 EJB 컨테이너는, 대규모 분산 객체 트랜잭션 처리를 필요로 하는 엔터프라이즈급 시스템 구축을 주요 목표로 했다. 이 기술은 서버 측 컴포넌트 모델을 표준화하여 기업의 복잡한 요구사항을 해결하는 데 기여했다.
EJB 컨테이너는 애플리케이션 서버 내에 구축되어 동작하며, 클라이언트의 요청을 받아 해당 EJB 컴포넌트를 찾아 실행하고, 결과를 반환하는 중간자 역할을 수행한다. 이 구조는 비즈니스 로직과 인프라스트럭처 관심사를 분리하는 데 핵심적이며, 현재는 Jakarta EE 생태계의 중요한 부분으로 진화해 왔다.
2. 역사와 배경
2. 역사와 배경
EJB 컨테이너의 역사는 EJB 사양과 J2EE 플랫폼의 발전과 깊이 연관되어 있다. 1990년대 후반, 기업용 소프트웨어는 점점 더 복잡해지고 분산 환경에서 운영될 필요성이 커졌다. 이러한 요구에 대응하여 썬 마이크로시스템즈는 서버 측 컴포넌트 모델인 EJB를 발표했으며, 이 컴포넌트들을 실행하고 관리할 런타임 환경으로서 EJB 컨테이너의 개념을 도입했다. EJB 1.0 사양이 1998년에 처음 공개되면서, 애플리케이션 서버 벤더들은 이 사양을 구현한 EJB 컨테이너를 자신들의 제품에 포함시키기 시작했다.
초기 EJB(주로 EJB 2.x까지)는 엔터프라이즈 애플리케이션의 핵심 비즈니스 로직과 지속성 로직을 모두 포괄하는 무거운 아키텍처로 설계되었다. 이 시기의 EJB 컨테이너는 엔터티 빈을 통한 객체-관계 매핑, 복잡한 원격 메서드 호출, 그리고 필수적인 XML 기반 배포 서술자 설정 등을 관리하는 복잡한 역할을 담당했다. 그러나 이로 인해 개발 생산성이 떨어지고 애플리케이션이 특정 애플리케이션 서버에 종속되는 문제가 발생하기도 했다.
이러한 복잡성에 대한 반동으로 등장한 경량 프레임워크(예: 스프링 프레임워크)의 도전과 개발자 커뮤니티의 피드백을 받아들여, EJB 3.0(2006년)은 혁신적인 단순화를 이루었다. 어노테이션의 도입으로 XML 설정이 대폭 줄었고, 지속성 관리는 JPA로 분리되었다. 이 변화에 따라 EJB 컨테이너의 역할도 보다 정제되었으며, 주로 세션 빈과 메시지 구동 빈의 생명주기 관리, 선언적 트랜잭션, 보안 같은 인프라 서비스 제공에 집중하게 되었다. 현재 EJB와 EJB 컨테이너는 자카르타 EE 생태계의 중요한 구성 요소로서 진화를 거듭하고 있다.
3. 아키텍처와 구성 요소
3. 아키텍처와 구성 요소
3.1. EJB 구성 요소
3.1. EJB 구성 요소
EJB 구성 요소는 엔터프라이즈 애플리케이션의 핵심 비즈니스 로직을 캡슐화하는 재사용 가능한 소프트웨어 컴포넌트이다. 이 구성 요소들은 EJB 컨테이너 내에서 실행되며, 컨테이너가 제공하는 트랜잭션 관리, 보안, 동시성 제어와 같은 기반 서비스를 통해 개발자는 복잡한 인프라 문제보다 순수한 비즈니스 로직 구현에 집중할 수 있다. EJB 구성 요소는 일반적으로 자바 클래스와 하나 이상의 인터페이스로 구성되며, 배포 서술자를 통해 컨테이너에 그 동작 방식을 알려준다.
주요 EJB 구성 요소 유형으로는 세션 빈, 메시지 구동 빈, 그리고 현재는 JPA로 대체된 엔터티 빈이 있다. 세션 빈은 클라이언트의 요청을 처리하는 비즈니스 프로세스를 구현하며, 상태를 유지하는 상태 저장 세션 빈과 상태를 유지하지 않는 무상태 세션 빈으로 나뉜다. 메시지 구동 빈은 JMS 메시지를 비동기적으로 처리하는 데 특화되어 있다. 과거 엔터티 빈은 영속성을 담당했으나, 복잡성과 성능 문제로 인해 현재는 JPA와 엔터티 객체가 그 역할을 대신하고 있다.
이러한 구성 요소들은 원격 메서드 호출 또는 로컬 인터페이스를 통해 클라이언트에 서비스를 노출한다. 개발자는 비즈니스 메서드를 구현한 후, 어노테이션이나 XML 기반의 배포 서술자를 사용하여 트랜잭션 속성이나 보안 역할 같은 선언적 행동을 지정한다. 이 선언적 메타데이터는 EJB 컨테이너가 런타임에 서비스를 투명하게 적용하는 근거가 된다.
3.2. 컨테이너 서비스
3.2. 컨테이너 서비스
EJB 컨테이너는 EJB 컴포넌트가 실행되는 런타임 환경으로, 애플리케이션 개발자가 직접 구현하기 복잡한 기반 서비스들을 표준화된 방식으로 제공하는 것이 핵심 역할이다. 이 컨테이너는 빈의 생성, 초기화, 실행, 소멸을 포함한 생명주기 관리를 전담하며, 개발자는 비즈니스 로직 구현에 집중할 수 있게 한다. 이러한 서비스 기반 아키텍처는 엔터프라이즈 애플리케이션의 복잡성을 낮추고 표준화된 개발을 가능하게 한다.
컨테이너가 제공하는 대표적인 서비스로는 트랜잭션 관리가 있다. 개발자는 선언적 방식으로 트랜잭션의 경계와 속성을 정의할 수 있으며, 컨테이너는 이를 자동으로 관리하여 데이터의 일관성을 보장한다. 또한 통합된 보안 서비스를 통해 인증과 권한 부여를 애플리케이션 코드와 분리하여 구성할 수 있다. 리소스 풀링은 데이터베이스 연결과 같은 고비용 자원을 효율적으로 관리하여 시스템 성능과 확장성을 높인다.
동시성 제어와 원격 통신 지원도 중요한 컨테이너 서비스다. 컨테이너는 여러 클라이언트 요청을 안전하게 처리하기 위한 동시성 메커니즘을 제공하며, RMI나 CORBA와 같은 분산 객체 프로토콜을 통해 빈을 원격에서 호출할 수 있게 한다. 의존성 주입과 같은 서비스를 통해 빈 간의 느슨한 결합을 유지하고, 인터셉터를 활용하여 크로스 커팅 관심사를 모듈화할 수 있다. 이러한 서비스들은 J2EE[4] 플랫폼의 핵심 가치인 엔터프라이즈급 안정성과 생산성을 실현하는 기반이 된다.
4. 주요 기능과 서비스
4. 주요 기능과 서비스
4.1. 트랜잭션 관리
4.1. 트랜잭션 관리
EJB 컨테이너의 핵심 서비스 중 하나는 트랜잭션 관리이다. 이는 데이터베이스나 메시징 시스템과 같은 여러 리소스에 걸친 작업의 원자성, 일관성, 고립성, 지속성을 보장하는 역할을 한다. 개발자는 복잡한 트랜잭션 제어 코드를 직접 작성하지 않고, 선언적 방식으로 트랜잭션의 경계와 속성을 정의할 수 있다.
주로 선언적 트랜잭션 관리 방식을 사용하며, 이는 배치 서술자나 어노테이션을 통해 트랜잭션의 동작을 지정하는 것을 의미한다. 예를 들어, 특정 엔터프라이즈 빈의 메서드가 호출될 때 자동으로 새로운 트랜잭션을 시작하거나, 기존 트랜잭션에 참여하도록 설정할 수 있다. 이를 통해 비즈니스 로직과 트랜잭션 관리 로직을 분리하여 애플리케이션의 유지보수성을 크게 향상시킨다.
컨테이너는 JTA를 통해 실제 트랜잭션 조정을 수행한다. 트랜잭션 매니저와 협력하여 분산 환경에서도 여러 리소스 매니저에 걸친 글로벌 트랜잭션을 투명하게 처리할 수 있다. 이는 2단계 커밋 프로토콜과 같은 메커니즘을 통해 데이터의 정합성을 유지한다.
프로그래밍적 트랜잭션 관리도 지원하여, 개발자가 UserTransaction 인터페이스를 사용하여 코드 내에서 트랜잭션의 시작, 커밋, 롤백을 명시적으로 제어할 수 있는 유연성을 제공한다. 이러한 강력한 트랜잭션 서비스는 금융이나 전자 상거래와 같이 데이터 정확성이 매우 중요한 엔터프라이즈 애플리케이션을 구축하는 데 필수적이다.
4.2. 보안
4.2. 보안
EJB 컨테이너는 애플리케이션의 보안 요구사항을 선언적으로 관리할 수 있는 서비스를 제공한다. 개발자는 비즈니스 로직을 구현한 EJB 컴포넌트에 대해, 특정 메서드나 클래스 수준에서 접근 제어 정책을 XML 기반의 배포 서술자에 정의한다. 이를 통해 인가 규칙을 소스 코드와 분리하여 설정할 수 있으며, 애플리케이션 서버의 보안 인프라와 통합된다.
주요 보안 메커니즘으로는 역할 기반 접근 제어가 있다. 시스템 관리자는 사용자와 그룹을 실제 역할에 매핑하고, 개발자는 해당 역할이 어떤 EJB 메서드를 실행할 수 있는지 선언한다. 예를 들어, '관리자' 역할은 모든 메서드에 접근할 수 있지만, '일반 사용자' 역할은 제한된 메서드만 호출할 수 있도록 설정한다. 이는 자바 인증 및 인가 서비스와 같은 표준 보안 API를 기반으로 구현된다.
이러한 선언적 보안 방식은 보안 정책의 변경이 소스 코드 수정과 재컴파일 없이 배포 설정만으로 가능하게 하여 유연성을 높인다. 또한, 트랜잭션 관리나 리소스 풀링과 같은 다른 컨테이너 서비스와 통합되어, 복잡한 엔터프라이즈 애플리케이션에서 일관된 보안 모델을 적용하는 데 기여한다.
4.3. 생명주기 관리
4.3. 생명주기 관리
EJB 컨테이너의 핵심 역할 중 하나는 세션 빈과 메시지 구동 빈을 포함한 다양한 EJB 컴포넌트의 생성, 활성화, 비활성화, 소멸 과정을 통제하는 생명주기 관리이다. 컨테이너는 애플리케이션 서버 내에서 동작하며, 빈의 상태에 따라 필요한 자원을 할당하거나 회수하여 효율적인 자원 관리를 가능하게 한다. 이를 통해 개발자는 복잡한 스레드 관리나 메모리 관리와 같은 저수준의 문제에서 벗어나 비즈니스 로직 구현에 집중할 수 있다.
생명주기 관리의 구체적인 예로 스테이트풀 세션 빈의 경우를 들 수 있다. 클라이언트의 요청에 따라 빈 인스턴스가 생성되고, 이후 일정 시간 동안 클라이언트의 상태를 유지하며 세션을 관리한다. 컨테이너는 사용 빈도가 낮은 인스턴스를 메모리에서 제거하여 패시베이션 상태로 전환하고, 필요 시 다시 액티베이션 과정을 거쳐 복원한다. 반면, 스테이트리스 세션 빈은 상태를 유지하지 않아 인스턴스 풀에서 자유롭게 재사용되며, 메시지 구동 빈은 JMS 메시지가 도착할 때마다 컨테이너에 의해 생성되어 비동기적으로 메시지를 처리한다.
이러한 생명주기 관리 메커니즘은 엔터프라이즈 애플리케이션의 확장성과 안정성을 보장하는 데 기여한다. 컨테이너가 인스턴스 풀을 관리함으로써 많은 수의 동시 요청을 효율적으로 처리할 수 있으며, 필요하지 않은 인스턴스를 적시에 제거함으로써 시스템 자원을 절약한다. 결과적으로, EJB 컨테이너는 Jakarta EE 플랫폼에서 엔터프라이즈급 비즈니스 로직 컴포넌트의 견고한 실행 기반을 제공하는 핵심 인프라 역할을 수행한다.
4.4. 리소스 풀링
4.4. 리소스 풀링
리소스 풀링은 EJB 컨테이너가 제공하는 핵심 서비스 중 하나로, 데이터베이스 연결과 같은 값비싼 리소스를 미리 생성해 풀에 보관하고, 필요할 때 애플리케이션에 할당하며, 사용 후 다시 풀로 반환하는 기법이다. 이는 매번 새로운 리소스를 생성하고 파괴하는 데 따르는 오버헤드를 줄여 시스템 성능과 확장성을 크게 향상시킨다. 특히 데이터베이스 연결을 관리하는 커넥션 풀은 EJB 애플리케이션에서 가장 일반적으로 활용되는 리소스 풀링의 예시이다.
EJB 컨테이너는 애플리케이션 서버 시작 시점이나 초기 요청 시점에 미리 정의된 수만큼의 데이터베이스 연결을 생성해 풀에 유지한다. 세션 빈이나 메시지 구동 빈이 데이터베이스 작업을 수행해야 할 때, 컨테이너는 풀에서 사용 가능한 연결을 꺼내 해당 EJB 인스턴스에 제공한다. 작업이 완료되면 연결은 즉시 종료되지 않고 풀로 반환되어 다음 요청을 대기하게 된다. 이 과정은 개발자가 직접 코드로 관리하지 않고, 컨테이너가 선언적 설정이나 관리 콘솔을 통해 정의된 정책에 따라 투명하게 처리한다.
리소스 풀링의 주요 이점은 반복적인 리소스 생성/해제 비용 절감, 응답 시간 단축, 그리고 동시 사용자 수 증가에 따른 시스템 부하를 효과적으로 관리할 수 있다는 점이다. 또한 풀의 최대/최소 연결 수, 유휴 시간 제한 등의 매개변수를 설정해 시스템 리소스 사용을 최적화할 수 있다. 이는 엔터프라이즈 애플리케이션이 요구하는 높은 가용성과 성능 요구사항을 충족하는 데 필수적이다.
5. EJB 유형
5. EJB 유형
5.1. 세션 빈
5.1. 세션 빈
세션 빈은 EJB에서 비즈니스 로직을 구현하는 데 사용되는 주요 구성 요소이다. 클라이언트의 요청을 처리하는 서비스 객체로서, 서버 측에서 실행되는 애플리케이션의 핵심 기능을 담당한다. 세션 빈은 상태를 유지하지 않는 무상태 세션 빈과, 특정 클라이언트와의 대화 상태를 유지하는 상태 저장 세션 빈, 그리고 비동기 호출을 처리하는 싱글톤 세션 빈으로 구분된다. 이들은 EJB 컨테이너에 의해 생성되고 관리되며, 트랜잭션과 보안 같은 엔터프라이즈 서비스를 컨테이너로부터 자동으로 제공받는다.
무상태 세션 빈은 클라이언트의 상태 정보를 저장하지 않아 확장성이 뛰어나며, 웹 서비스 엔드포인트로 자주 사용된다. 상태 저장 세션 빈은 쇼핑 카트처럼 사용자별 세션 상태를 유지해야 하는 경우에 적합하다. 싱글톤 세션 빈은 애플리케이션 전체에서 단 하나의 인스턴스만 존재하여, 애플리케이션 시작 시 초기화되거나 애플리케이션 전반에 걸쳐 공유 데이터를 캐시하는 용도로 활용된다.
세션 빈은 원격 메서드 호출 또는 로컬 인터페이스를 통해 접근할 수 있으며, 의존성 주입을 통해 다른 EJB나 자바 EE 리소스를 쉽게 참조할 수 있다. 이는 복잡한 엔터프라이즈 애플리케이션에서 비즈니스 로직 계층을 구성하는 표준적인 방법으로 자리 잡았다.
5.2. 메시지 구동 빈
5.2. 메시지 구동 빈
메시지 구동 빈(Message-Driven Bean, MDB)은 자바 메시지 서비스(JMS) 메시지나 다른 메시징 시스템의 메시지를 비동기적으로 수신하여 처리하는 EJB 유형이다. 세션 빈이나 엔터티 빈과 달리 프로그램적으로 직접 호출할 수 있는 클라이언트 뷰를 제공하지 않으며, 오직 메시지가 도착했을 때 컨테이너에 의해 자동으로 호출된다. 이는 메시지 지향 미들웨어(MOM)와 엔터프라이즈 애플리케이션을 통합하는 표준화된 방법을 제공한다.
MDB는 javax.jms.MessageListener 인터페이스를 구현하며, 메시지 수신 시 컨테이너가 onMessage() 메서드를 호출한다. 개발자는 이 메서드 내에서 메시지 내용을 파싱하고 필요한 비즈니스 로직을 수행하면 된다. EJB 컨테이너는 메시지의 수신, 트랜잭션 관리, 보안, 동시성, 리소스 풀링 등 복잡한 인프라 서비스를 처리하여 개발자가 순수한 비즈니스 로직에 집중할 수 있게 한다.
주요 사용처는 비동기 통신이 필요한 시나리오다. 예를 들어, 주문 처리 시스템에서 주문 요청을 JMS 큐에 넣으면 MDB가 이를 꺼내 재고 관리나 결제 처리 등의 작업을 수행할 수 있다. 이는 시스템 간의 느슨한 결합을 가능하게 하고, 처리 부하 분산 및 시스템 신뢰성 향상에 기여한다. 또한 Jakarta EE 플랫폼의 확장으로, JMS 외에도 다른 메시징 시스템(예: Java API for RESTful Web Services(JAX-RS)를 통한 이벤트)을 수신하도록 확장 가능하다.
MDB의 장점은 엔터프라이즈급 메시지 처리의 복잡성을 추상화한다는 점이다. 그러나 메시지 처리 로직이 애플리케이션 서버 내부에 묶인다는 점과, 경량화된 마이크로서비스 아키텍처 및 이벤트 드리븐 아키텍처의 등장으로 Apache Kafka나 RabbitMQ와 같은 전용 메시징 시스템과의 연동에 초점이 더 많이 맞춰지면서, 최신 애플리케이션에서의 상대적 비중은 다소 줄어드는 추세이다.
5.3. 엔터티 빈 (JPA로 대체)
5.3. 엔터티 빈 (JPA로 대체)
엔터티 빈은 EJB 2.x 스펙까지 존재했던 영속성 계층을 담당하는 컴포넌트 유형이다. 이는 관계형 데이터베이스의 테이블 레코드를 객체 지향 프로그래밍의 객체로 매핑하는 객체 관계 매핑 개념을 구현한 것이었다. 엔터티 빈은 컨테이너가 제공하는 트랜잭션과 보안 서비스를 활용할 수 있었지만, 개발 모델이 복잡하고 무겁다는 비판을 받았다. 특히 원격 인터페이스와 로컬 인터페이스, 홈 인터페이스를 모두 정의해야 했으며, EJB QL이라는 제한적인 쿼리 언어를 사용해야 했다.
이러한 복잡성과 성능 문제로 인해 엔터티 빈은 자바 커뮤니티 내에서 광범위한 비판을 받았고, 더 간결하고 강력한 영속성 프레임워크에 대한 요구가 높아졌다. 이에 따라 등장한 것이 JPA이다. JPA는 EJB 3.0 스펙의 일부로 표준화되었으며, 엔터티 빈을 완전히 대체하는 새로운 영속성 모델을 제시했다. JPA는 일반 자바 객체에 간단한 어노테이션을 추가하는 방식으로 ORM을 구현하며, EJB 컨테이너에 의존하지 않고도 독립적으로 사용할 수 있다.
결과적으로, EJB 3.0 이후의 현대적 자카르타 EE 애플리케이션에서는 엔터티 빈을 사용하지 않는다. 모든 데이터베이스 연동과 객체 관계 매핑 요구사항은 JPA 구현체인 하이버네이트, 이클립스링크 등을 통해 처리된다. 따라서 '엔터티 빈'은 현재는 주로 EJB의 역사적 배경과 진화 과정을 설명할 때 언급되는 과거의 기술 구성 요소로 자리 잡았다.
6. 동작 방식
6. 동작 방식
EJB 컨테이너의 동작 방식은 개발자가 작성한 EJB 컴포넌트를 배포하고, 런타임 시 해당 컴포넌트의 생명주기를 관리하며, 필요한 엔터프라이즈 서비스를 투명하게 제공하는 과정을 말한다. 기본적으로 클라이언트는 EJB 객체에 직접 접근하지 않으며, 컨테이너가 생성한 프록시 객체를 통해 간접적으로 접근한다. 이 프록시 객체는 스텁의 역할을 하여, 클라이언트의 메서드 호출을 가로채 컨테이너 서비스(예: 트랜잭션 시작, 보안 검사)를 적용한 후 실제 빈 인스턴스에게 요청을 전달한다.
구체적인 동작 과정은 다음과 같다. 먼저, 개발자는 세션 빈이나 메시지 구동 빈과 같은 EJB 컴포넌트를 작성하고, 배포 서술자를 통해 트랜잭션 속성이나 보안 역할 같은 메타데이터를 정의한다. 이 컴포넌트를 EJB 컨테이너가 탑재된 애플리케이션 서버에 배포하면, 컨테이너는 배포 서술자를 읽고 해당 EJB에 대한 프록시 객체(홈 객체와 원격 객체)를 생성한다. 클라이언트는 JNDI를 사용하여 이 프록시 객체를 조회한 후 비즈니스 메서드를 호출한다.
클라이언트의 메서드 호출이 발생하면, 컨테이너는 호출을 가로채 인터셉터 체인을 실행한다. 이 단계에서 선언적으로 정의된 트랜잭션 관리가 이루어지며, 필요한 경우 새로운 트랜잭션을 시작하거나 기존 트랜잭션에 참여한다. 또한 메서드 호출자의 보안 자격 증명을 확인하여 접근을 통제한다. 이러한 서비스 적용 후, 컨테이너는 적절한 빈 인스턴스를 풀에서 가져오거나 새로 생성하여 메서드 호출을 위임한다. 호출이 완료되면 트랜잭션을 커밋하거나 롤백하며, 빈 인스턴스를 정리한다.
이러한 방식으로 EJB 컨테이너는 개발자가 복잡한 인프라 코드를 작성하지 않고도 비즈니스 로직에 집중할 수 있도록 한다. 컨테이너가 제공하는 선언적 서비스는 배포 서술자나 어노테이션을 통해 설정되므로, 애플리케이션의 유지보수성과 이식성이 향상된다. 결과적으로 EJB 모델은 다중 사용자 환경에서의 안정성과 확장성을 보장하는 서버 사이드 컴포넌트 아키텍처의 기반을 제공한다.
7. 장단점
7. 장단점
EJB 컨테이너는 엔터프라이즈급 애플리케이션 개발을 위한 강력한 플랫폼을 제공하지만, 그에 따른 복잡성과 오버헤드도 존재한다.
주요 장점은 엔터프라이즈 애플리케이션 개발의 복잡성을 대폭 줄여준다는 점이다. 개발자는 트랜잭션 관리, 보안, 동시성 제어, 리소스 풀링과 같은 복잡한 인프라 수준의 서비스를 직접 구현할 필요 없이, 비즈니스 로직에 집중할 수 있다. 이는 썬 마이크로시스템즈가 제시한 표준화된 컴포넌트 모델 덕분에 가능하다. 또한, EJB는 J2EE 스펙의 핵심 부분으로, 다양한 애플리케이션 서버 간의 이식성을 보장하며, 대규모 분산 시스템에 필요한 확장성과 안정성을 제공한다.
반면, 단점은 상당한 복잡성과 성능 오버헤드에서 비롯된다. 초기 EJB 스펙은 무거운 컴포넌트 모델과 복잡한 배포 서술자를 요구했으며, 이는 개발과 테스트를 느리게 만들었다. 특히 엔터티 빈은 객체-관계 매핑 기능이 복잡하고 비효율적이라는 비판을 받아 결국 JPA로 대체되었다. 또한, 컨테이너가 제공하는 모든 서비스는 런타임 시 추가적인 리소스를 소모하여, 가벼운 웹 애플리케이션에는 과도한 부담이 될 수 있다.
이러한 장단점은 기술의 발전과 함께 진화했다. EJB 3.0 이후 어노테이션 기반의 단순화된 프로그래밍 모델이 도입되면서, 많은 복잡성 문제가 해소되었다. 특히 경량화된 EJB와 스프링 프레임워크 같은 대안의 등장은 개발자에게 더 넓은 선택지를 제공하게 되었다.
8. 관련 기술 및 표준
8. 관련 기술 및 표준
EJB 컨테이너는 J2EE (현재 Jakarta EE) 플랫폼의 핵심 구성 요소로서 동작한다. 이 플랫폼은 엔터프라이즈 애플리케이션을 구축하기 위한 다양한 스펙과 API의 집합체로, 서블릿, JSP, JMS, JTA 등과 함께 통합되어 사용된다. 특히 JPA는 EJB의 엔터티 빈을 대체하는 영속성 관리 표준으로 발전했으며, 트랜잭션 관리를 위해 JTA와 밀접하게 연동된다.
EJB 기술의 진화는 자바 커뮤니티 프로세스를 통해 이루어졌으며, EJB 3.0 이후로는 복잡성을 줄이고 POJO 기반의 간소화된 프로그래밍 모델을 채택하는 방향으로 변화했다. 이는 스프링 프레임워크와 같은 경량화된 자바 프레임워크의 등장과 경쟁 관계에 있었음을 보여준다. 현재 EJB는 마이크로서비스 아키텍처와 클라우드 네이티브 환경에 적합하도록 EJB 3.2 및 Jakarta EE의 일부로 계속 발전하고 있다.
9. 여담
9. 여담
EJB 컨테이너는 엔터프라이즈 애플리케이션 개발의 초기 단계에서 복잡한 분산 컴퓨팅 문제를 해결하기 위한 중요한 시도였다. 특히 코바와 같은 기존 미들웨어 기술에 비해 자바 언어의 이식성과 객체 지향 프로그래밍의 장점을 결합했다는 점에서 주목받았다. 그러나 초기 EJB 1.0과 EJB 2.0 스펙은 과도하게 복잡하고 무거운 것으로 평가받으며, 개발자들 사이에서 '오버엔지니어링'의 대표 사례로 꼽히기도 했다.
이러한 복잡성에 대한 반동으로 등장한 경량 프레임워크들이 EJB의 지형도를 크게 바꾸었다. 로드 존슨이 2002년에 저술한 "J2EE Design and Development"는 EJB 없이도 엔터프라이즈급 애플리케이션을 구축할 수 있음을 보여주었고, 이 아이디어는 이후 스프링 프레임워크의 탄생으로 이어졌다. 스프링은 의존성 주입과 관점 지향 프로그래밍 같은 개념을 바탕으로 훨씬 단순하고 테스트하기 쉬운 프로그래밍 모델을 제시하며 큰 인기를 얻었다.
결국 EJB 스펙 자체도 이러한 변화의 흐름을 따라가야 했다. EJB 3.0은 어노테이션을 도입하고 XML 설정을 대폭 줄이며, POJO 기반의 단순화된 모델로 거듭났다. 특히 엔터티 빈은 JPA로 사실상 대체되어 영속성 계층의 표준 역할을 넘겨주었다. 오늘날 EJB, 특히 세션 빈은 자카르타 EE 생태계 내에서 여전히 사용되지만, 그 역할은 과거에 비해 훨씬 경량화되고 특화된 영역으로 축소되었다.
EJB 컨테이너의 역사는 엔터프라이즈 소프트웨어 개발 패러다임의 진화를 보여주는 사례이다. 이는 기술이 지나치게 복잡해지면, 결국 시장과 개발자 커뮤니티가 더 단순한 대안을 찾아내어 생태계 전체를 재편한다는 점을 시사한다. EJB의 등장과 변화는 소프트웨어 공학에서 표준화의 이점과 실용성 사이의 지속적인 긴장 관계를 잘 보여준다.
