Eclipse RCP에서 응용 프로그램을 개발 중입니다. 서비스 설계와 관련된 설계 결정에 도움이 필요합니다.OSGi 서비스 아키텍처 : 소비자의 요청에 따라 서비스 생성
다른 모듈에 REngine
개체를 제공하는 데 사용되는 번들이 있습니다. REngine
은 여러 가지 방법으로 구현 될 수있는 계산 엔진에 대한 인터페이스입니다. 번들은 원격 서버에 연결하거나 로컬 계산 스레드를 시작하여 REngine 인스턴스를 제공합니다. 일부 번들은 GUI로 구성해야합니다 (헤드리스 플랫폼에서도 사용할 수 있어야합니다). 클라이언트 번들은 병렬 계산을 위해 복수 REngine
개체를 요청할 수 있습니다.
나는 현재 REngine
서비스를 제공하기 위해이 모듈들을 등록하고 있습니다. 서비스는 로컬 계산 인스턴스 또는 원격 (서버) 인스턴스를 시작하는 ServiceFactory에 의해 작성됩니다. 클라이언트는 REngine
클래스의 모든 서비스 등록을 시도하고 올바른 서비스 등록을 선택해야합니다.
class API.REngine { ... }
class REngineProvider.Activator {
public void start(BundleContext ctx) {
ctx.registerService(REngine.class.getName(), new REngineFactory(), null);
}
}
class REngineProvider.REngineFactory implements ServiceFactory {
public Object getService(Bundle bundle, ServiceReference reference) {
return new MyREngineImplementation();
}
public void ungetService(REngine service) {
service.releaseAssociatedResources();
}
}
class RConsumer.Class {
REngine getREngine() {
ServiceReference[] references = bundleContext.getAllServiceReferences(REngine.class.getName(), null);
for(ServiceReference ref: references) {
try {
return bundleContext.getService(ref);
} catch (Exception e) {} // too bad, try the next one
}
}
}
나는이 모델을 유지하고자 다음과 같이
이 작업을 수행하는 코드
요약 될 수있다. OSGi 서비스 스펙은 REngine 오브젝트가 더 이상 필요하지 않을 때 해제해야하는 살아있는 오브젝트라는 내 비즈니스 요구 사항과 일치합니다.그러나 등록 된 서비스는 번들 당 하나의 서비스 인스턴스 만 제공 할 수 있습니다. 두 x 째 서비스가 요청되면 캐시 된 인스턴스가 리턴됩니다 (새 인스턴스를 작성하는 대신). 이것은 내 요구 사항과 일치하지 않습니다. 번들은 동일한 공급자로부터 여러 개의 REngine 객체를 가져올 수 있어야합니다.
다른 OSGi 프레임 워크 클래스를 살펴 보았지만 아무 것도 도움이되지 않습니다. 화이트 보드 모델이 있지만 REngineProvider 번들에서 사용하는 REngineRequestService를 등록하면 실제 REngine을 제공 할 수 있습니다.
OSGi에서 어떻게 구현합니까?
- 쉬운 사용 및
REngineProvider
번들 해제 : 참고로, 여기 요구 사항을 내 목록입니다. 클라이언트 코드는 대신 다른 공급자를 사용합니다. - REngineProvider 번들 구성.
- 클라이언트 번들 당 복수
REngine
개의 인스턴스. REngine
인스턴스의 명시적인 릴리스REngine
생성이 실패 할 수 있습니다. 클라이언트 모듈은 이유를 알 수 있어야합니다.
그냥 내가 나중에 참조로 선택한 솔루션을 추가 할 수 있습니다. OSGi Services 플랫폼은 "서비스 요청"을 위해 만들어진 것이 아닙니다. 서비스를 생성하는 공급자 번들과 서비스를 찾고 사용할 수있는 클라이언트 번들입니다. 사용자 요청 당 서비스에 대해 자동 "공장"을 제공하는 것은 불가능합니다.
선택한 솔루션은 OSGi whiteboard model입니다. 첫눈에, 이것은 관리하기가 매우 어려울 것 같지만, Blueprint
은 많은 도움이 될 수 있습니다!
공급자 청사진XML 파일 :
<reference-list interface="org.application.REngineRequest"
availability="optional">
<reference-listener
bind-method="bind" unbind-method="unbind">
<bean class="org.provider.REngineProvider"/>
</reference-listener>
클래스 REngineRequest
공유 API 입력에 제공 그의 REngine 개체를 허용하는 클래스 또는 인 설정 작성이 작동하지 않은 이유를 설명하는 예외입니다. 클라이언트에 대한
REngineRequest req = new REngineRequest();
ServiceRegistration reg = bundleContext.registerService(req, REngineRequest.class.getName(), engineCreationProperties);
req.getEngine().doSomeStuff();
reg.unregister();
우리는 클라이언트가 REngine을 사용하는 동안 공급자가 멈추지 않을 것이라는 가정을합니다. 이 경우 REngine
이 유효하지 않게됩니다.
DS 대신 BluePrint 및 PROTOTYPE 주석을 사용 하시겠습니까? 나는 그 차이를보기 힘들다. – parasietje
나는 청사진과 프로토 타입 범위를 제안하려고했습니다. 청사진에는 선언적 서비스보다 더 많은 노브가있어 여기에서 유용 할 수 있습니다. –
불행히도, 객체를 만들 때 컨텍스트 (속성)가 필요합니다. 간단한 팩토리 메서드를 지정할 수는 없지만 인스턴스화 된 클래스를 지정해야한다는 것은 큰 힘이됩니다. 청사진에 그런 희망이 있기를 바랍니다! – parasietje