4.2. Application Context Creation

Extender 번들은 application context를 비동기적으로 생성한다.
– OSGi 서비스 플랫폼 시작 속도를 빠르게 해준다.
– 서비스들 간의 종속성으로 인한 데드락의 위험이 없다.
– 따라서 스프링 DM을 사용한 번들의 application context가 만들어지기 전에 STARTED 상태가 될 수 있다.
– 5.1을 참조하면, 동기적으로 번들을 생성하도록 설정하는 방법을 참조할 수 있다.
– 만약 application context를 무슨 이유에서건 생성하지 못했다면, 로그를 남기고 번들은 여전히 STARTED 상태다. 단, 해당 번들이 export한 서비스는 하나도 없는 상태로..

1. Mandatory Service Dependencies

OSGi 서비스의 가용성에 필수적인 mandatory 의존성을 선언하면, 해당 application context의 생성은 OSGi 서비스 레지스트리를 통해서 필수적인 의존성을 만족 시킬 때까지 대기 block 한다.
– 6장 서비스 레지스트리에서 필수적인 서비스 레퍼런스를 찾지 못할 때 어떤일이 벌어지는 지 설명한다.
– 이런 원리로 스프링 DM은 번들들이 어떤 순서대로 시작되는 상관없이 필수적인 종속성을 가지도록 보장한다.
– 타임아웃을 설정할 수 있다. 기본은 5분이다. timeout 지시자에 그 값을 설정할 수 있다. 5.1 참조.
– 해당 번들 실행시 필요한 서비스를 못찾으면 바로 application context 생성을 실패하도록 설정할 수 있다.(fail-fast) 이 경우 해당 번들은 ACTIVE 상태가 아니라 RESOLVED 상태로 남게 된다.

2. Application Context Service Publication

번들의 application context 생성이 완료되면, application context 객체는 자동으로 OSGi 서비스 레지스트리에 하나의 서비스로 등록이 된다.
– org.springframework.context.ApplicationContext 인터페이스 아래로 공개된다.
– 공개된 서비스들은 org.springframework.context.service.name 이라는 서비스 속성을 가지고 있다. 이 값은 해당 application context를 가지고 있는 번들의 Symbolic Name으로 설정된다.
– application context를 서비스로 등록하는 걸 막을 수도 있는데, 이건 5.1에서 살펴본다.

노트: Application context가 서비스로 등록되는 이유는 testing, administration, management를 하기 위해서다. context 객체에 런타임시 접근하여 getbean() 같은 것을 호출하는 행위를 하지 말기 바란다. 다른 번들의 application context에 등록되어 있는 Bean을 가져오고 싶을 때 권장하는 방법은 일단 OSGi 서비스로 해당 bean을 export하고, 그걸 참조하고 싶어하는 context에서 서비스로 import하는 것이다. 이렇게 서비스 레지스트리를 통해서 가져와야 그에 상응하는 버전에 해당하는 서비스만 참조하는 것을 보장하며, OSGi 플랫폼이 동적으로 관리하는 서비스를 가져올 수 있다.

4.1. The Spring Dynamic Modules Extender bundle

스프링 DM은 org.springframework.osgi.bundle.extender라는 번들을 제공한다.

이 번들은 번들에서 사용할 스프링 application context를 생성해준다. 스프링 웹 애플리케이션의 ContextLoaderListener와 같은 역할을 한다.

extender 번들이 설치 installed 되고 시작 started 되면 이미 Activce인 상태의 번들 중에 스프링 DM을 사용하는 번들을 찾아서 application context를 만들어 준다.

또한, 번들 시작 이벤트를 주시 listening 하다가 스프링 DM을 사용한 번들이 시작되면 application context를 만들어 준다.

5.1에서 extender가 어떻게 스프링 DM을 사용한 번들로 인식하는지 알아본다.

Extender Pattern

“allow other bundles to extend the functionality in a specific domain”
특정 도메인에 있는 기능을 다른 번들들이 확장할 수 있도록 하는 패턴.

Bundles and Application Contexts

OSGi 번들

OSGi에서 배포 단위는 번들.
번들은 런타임시에 세 가지 steady 상태 중 하나가 됨. installed, resolved, active.
번들은 서비스를 OSGi 서비스(객체) 레지스트리에 등록하여 다른 번들이 해당 서비스를 사용하도록 할 수 있슴.
번들은 패키지를 노출 시켜서 다른 번들들이 노출 된 타입들을 import 해서 사용하도록 할 수 있음.

스프링 Application Context

스프링의 기본적인 모듈화 단위는 application context.
이 안에 스프링이 관리할  빈들을 담고 있다.
상속 구조를 가질 수 있다. 하위 context에서 상위 context에 있는 빈들을 참조할 수 있지만, 그 반대는 안 된다.
(Spring MVC를 잘 보면 이 구조가 있죠.)
스프링의 exporter나 factory bean들은 외부 클라이언트쪽 application context에서 해당 bean에 대한 레퍼런스를 사용할 수 있도록 제공해준다.
(Spring의 Expoter들은 JMS나 RPC 쪽을 보면 잘 나와 있습니다. 아주 일관된 패턴으로 Exporter들을 제공해 줍니다.)

OSGi 번들과  스프링 Application Context

잘 어울린다.
스프링 DM을 사용해서, 번들은 번들 내부에 있는 객체들(bean)을 생성하고, 설정하고, 묶고, 꾸며줄 applicaion context를 가질 수 있다.
그런 Bean들 중에 일부를 선택적으로 OSGi 서비스로 노출시켜서 외부의 다른 번들에서 사용할 수 있도록 할 수 있고, 그런 빈들은 깔끔하게Transparently 다른 OSGi 서비스에 주입 될 수 있다.