2009-12-24 7 views

답변

14

ServiceLoader이 대부분 사용자의 요구에 맞는 경우 클래스 경로에있는 파일이있을 때 서비스 검색을 찾고 있다고합니다. 이는 OSGi가 제공하는 것의 일부에 지나지 않습니다.

OSGi를 사용하면 응용 프로그램이 실행되는 동안 번들을 동적으로 설치하고, 서비스를 광고하고, 광고를 취소하고, 번들을 제거 할 수 있습니다. 또한 서비스 소비자로서, 술어 쿼리를 필터링하여 열심히 검색하고 제공되는 서비스 제공 업체가 올 때와 출근 할 때를 감지 할 수 있습니다. 이러한 번들은 클래스 경로에있을 필요가 없으며 다양한 형태로 제공 될 수 있습니다. jar 파일과 "exploded directories"는 내가 기억하는 두 가지입니다.

대조적으로 ServiceLoader은 검색 가능한 공장을 노출합니다. 일반적으로 팩토리 스타일의 인터페이스를 생성하여 제공자가 적절한 문자 세트 이름을 CharsetDecoder으로 매핑하는 것과 같은 적절한 서비스를 제공 할 수 있는지 여부를 결정합니다. 이러한 공급자로부터 서비스를 획득하고 릴리스하기위한 공식화 된 프로토콜은 없습니다. OSGi는 소비자의 서비스에 대한 바인딩 및 바인딩 해제를 공식화합니다. 소비자는 새로운 공급자가 온라인 상태가되면 알림을받을 수 있으며 소비자는 서비스 인스턴스를 획득하고 해제 할 때 알림을받을 수 있습니다. 이 라이프 사이클 컨트롤이 서비스에 중요하고 OSGi를 잊어 버린 경우 직접 작성해야합니다. 은 그리 멀지 않습니다.

열정적 인 서비스 조회 및 사용보다는 좀 더 수동적 인 선언적 접근 방식을 사용하여 OSGi 종속성 관리자 중 한 명이 명시된 요구 사항을 사용 가능한 서비스 제공자에게 제공하도록 할 수 있습니다. 선택할 수있는 많은 종속성 관리자가 있습니다. Spring Dynamic Modules은 가장 뛰어난 기능 중 하나입니다.

OSGi는 다른 많은 "미들웨어"기능을 제공합니다. 귀하의 질문은 대부분 ServiceLoader을 선택함으로써 누락 된 부분에 초점을 맞추기 때문에 여기에서 귀하를 팔려고하지 않을 것입니다.

+0

OSGi가 무엇인지 정말 고마워.ServiceLocator가 가지고있는 것만을 정말로 필요로합니다. 그리고 그것이 내재되어 있다는 것에 감사드립니다. 의심스러워서 질병에 걸려 있어야한다고 생각하기 전에 들어 본 적이 없습니다. –

+2

현재 프로젝트에서'ServiceLoader'를 사용하고 있습니다. 클래스 경로에 확장 파일을 Jar 파일로 푸시해야한다는 단점이 있습니다. (우리의 응용 프로그램은 클래스 경로에서 최종 사용자가 부지런히 움직이는 것을 권장하지 않습니다.) , 2) 동일 서비스 인터페이스의 형제 공급자가 소비자에게 노출되는 불특정 순서. 후자는 사용자가 제공하는 확장이 응용 프로그램의 기본 서비스보다 더 바람직해야한다는 것과 같이 "우선 순위"를 통합하는 것을 어렵게 만듭니다. 따라서 'ServiceLoader'는 공급자가 서로 겹치거나 경쟁하지 않을 때 가장 잘 사용됩니다. – seh

3

단순한 서비스 검색에만 관심이 있다면 ServiceLoader는 소비자를 공급자와 분리 할 수있는 간단한 방법입니다. 그러나 서비스를 함께 작성하는 데 도움이되지는 않습니다.

예를 들어 서비스 A가 서비스 B를 사용해야한다고 가정합니다. 이것은 "서비스 종속성"입니다 ...하지만 B를 사용할 수없는 경우 어떻게해야합니까? OSGi에서 우리는 B가 사용 가능하지 않다면 A가 될 것이라는 것을 정할 수 있습니다 - 의존성이 필수적이라고 가정하십시오; 선택적 종속성도 지원할 수 있습니다. 반면 ServiceLoader를 사용할 때 서비스 A는 클래스 패스에있는 JAR이있는 한 가용성을 제어 할 수 없으므로 필요한 "백엔드"서비스가 없어도 서비스 A가 제공해야합니다.

ServiceLoader에서 염두에 두어야 할 또 다른 사항은 검색 메커니즘을 추상화하는 것입니다. 게시 메커니즘은 아주 훌륭하고 깨끗하며 선언적입니다. 하지만 (java.util.ServiceLoader를 통한) 조회는 지옥만큼이나 못생긴 일이며, 전역 가시성을 갖지 않는 환경 (예 : OSGi 또는 Java EE)에 코드를 넣으면 끔찍한 결과를 초래하는 classpath 스캐너로 구현됩니다. 코드가 뒤죽박죽이되면 OSGi에서 나중에 실행하기가 어려울 것입니다. 시간이되면 대체 할 수있는 추상화를 작성하는 것이 좋습니다.

+1

나중에 OSGi로 쉽게 마이그레이션 할 수 있도록 ServiceLoader에 대한 간단한 추상화에 대해 자세히 설명 할 수 있습니까? 현재 클래스 패스의 모듈을 검색하기 위해 코어 구성 요소에 serviceloader 메커니즘을 사용하는 12 또는 13 개의 jar 파일로 분할 된 프레임 워크가 있습니다. 앞으로 OSGi에서 프레임 워크가 훌륭하게 작동하지만 OSGi에 의존하지 않기를 바랍니다. 지금까지 나는 이중성을 성취하는 방법을 볼 수 없다. ServiceLoader 메카니즘을 사용할 때 OSGi의 절반 밖에되지 않는 것이 가능한가? – Chris

+1

가장 좋은 추상화는 의존성 주입과 같은 것입니다. 일부 서비스 "Foo"가 필요한 코드에서 해당 서비스를 조회하지 말고 단순히 setFoo() 메소드를 통해 주입하도록 허용하십시오. 다른 클래스에서 ServiceLoader를 호출하여 Foo 인스턴스를 가져 와서 필요한 코드에 삽입합니다. 나중에 OSGi로 이동하는 경우 두 번째 클래스를 스크랩하고 Declarative Services 또는 Blueprint를 사용하여 OSGi 서비스 주입을 처리하십시오. –

관련 문제