OSGi 입문: Declarative Services 와 의존

http://230996.blog.chinajavaworld.com/entry/3719/0/
 
이 클립 스 존 'OSGi 입문' 시리즈 강좌 에 오신 것 을 환영 합 니 다.오늘 수업 에 들 어가 기 전에 나 는 네가 모든 강좌 의 이전 부분 을 나의 개인 블 로그 에서 찾 을 수 있 기 를 바란다.지난번 에 우 리 는 처음으로 Declarative Service 를 접 했다.이번 에는 Declarative Service 소비자 쪽 을 살 펴 보 겠 습 니 다.이전에 우 리 는 자바. lang. Runnable 인터페이스 에 서 비 스 를 등록 한 것 을 기억 합 니 다.현재 우 리 는 이 서비스 에 의존 하 는 구성 요 소 를 만 들 것 입 니 다.토론 한 바 와 같이 Declarative Services 규범 은 이전 과정 에서 쓴 OSGi 'glue' 코드 가 아 닌 코드 에 초점 을 맞 추 는 모든 응용 논리 입 니 다.이 를 감안 하여 우 리 는 코드 에 잠입 할 뿐 이 므 로 프로젝트 를 만들어 야 합 니 다.다음은 마지막 과정 에서 같은 절차 이지 만 'Simple Importer' 를 프로젝트 이름 으로 사용 합 니 다.현재 브 라 우 저 에서 다음 코드 를 복사 하여 새 Eclipse 프로젝트 의 src 폴 더 에 붙 여 넣 습 니 다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package org.example.ds;
 
import org.eclipse.osgi.framework.console.CommandInterpreter;
import org.eclipse.osgi.framework.console.CommandProvider;
 
public class SampleCommandProvider1 implements CommandProvider {
	
	private Runnable runnable;
	
	public synchronized void setRunnable(Runnable r) {
		runnable = r;
	}
	public synchronized void unsetRunnable(Runnable r) {
		runnable = null;
	}
	public synchronized void _run(CommandInterpreter ci) {
		if(runnable != null) {
			runnable.run();
		} else {
			ci.println("Error, no Runnable available");
		}
	}
	public String getHelp() {
		return "\trun - execute a Runnable service";
	}
}

이 종 류 는 CommandProvider 인 터 페 이 스 를 실현 합 니 다. 이것 은 Equinox 를 실행 할 때 "osgi >" 프롬프트 에서 효과 적 인 명령 집합 을 확장 하 는 데 사 용 됩 니 다.CommandProvider 를 쓰 는 이 유 는 코드 의 상호작용 을 테스트 하 는 데 편리 한 방법 을 제공 하기 때 문 입 니 다.IBM developerWork 의 Chris Aniszczyk 문장. 에서 더 많은 명령 제공 기 에 대한 상세 한 토론 이 있 습 니 다.이 클래스 에서 OSGi API 를 호출 하지 않 았 습 니 다. 사실상 org. osgi. * 패키지 에서 아무것도 가 져 올 필요 가 없습니다.Google 이 의존 하 는 이 서 비 스 는 이 경우 자바. lang. Runnable 의 인 스 턴 스 입 니 다. 저 희 는 setRunnable 방법 으로 사용 하고 unsetRunnable 방법 으로 가 져 갑 니 다.우 리 는 이것 이 의존 주입 의 형식 이 라 고 볼 수 있다.다른 두 가지 방법, getHelp 과run 은 명령 제공 기 를 위 한 것 입 니 다.맞아요. "run" 은 재 미 있 는 이름 입 니 다. 밑줄 로 시작 하지만 그것 은 Equinox 콘 솔 API 의 이상 한 특성 일 뿐 OSGi 나 Declarative Service 는 아무것도 하지 않 습 니 다.밑줄 치기 시작 모드 를 사용 하 는 방법 은 Equinox 콘 솔 에서 명령 으로 바 뀌 었 기 때문에 라 는 것 을 제공 합 니 다.run 방법 에 "run" 명령 을 추가 하 였 습 니 다.또한 이 클래스 에 대해 서 는 runnable 필드 가 스 레 드 로 안전하게 업데이트 되 고 접근 할 수 있 도록 관심 을 가 져 야 합 니 다.스 레 드 안전 은 OSGi 에서 상당히 중요 하 다. 왜냐하면 그것 은 본질 적 으로 다 중 스 레 드 이기 때문이다.솔직히 말 해서, 우 리 는 시종 우리 의 코드 를 안전 한 라인 으로 써 야 한다.이전 처럼 DS 성명 을 포함 한 XML 파일 을 제공 해 야 합 니 다.다음 OSGI - INF / commandprovider 1. xml 을 plug - in 항목 으로 복사 합 니 다.
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<component name="commandprovider1">
	<implementation class="org.example.ds.SampleCommandProvider1"/>
	<service>
		<provide interface="org.eclipse.osgi.framework.console.CommandProvider"/>
	</service>
	<reference name="RUNNABLE"
		interface="java.lang.Runnable"
		bind="setRunnable"
		unbind="unsetRunnable"
		cardinality="0..1"
		policy="dynamic"/>
</component>

이것 은 우리 가 지난번 에 서술 을 소홀히 한 또 다른 중요 한 절차 다.(Seamus Venasse 가 지적 해 주 셔 서 감사합니다.) build. properties 파일 을 plug - in 항목 에 편집 하고 OSGI - INF 폴 더 가 선택 되 었 는 지 확인 해 야 합 니 다.Bundle 이 Eclipse 내 보 내기 마법사 로 내 보 낼 때 폴 더 가 포함 되 어 있 거나 PDE Build 로 만들어 져 야 합 니 다.그러면 Bundle 의 manifest 에 다음 줄 을 추가 해 야 합 니 다.
1
Service-Component: OSGI-INF/commandprovider1.xml

이 정 의 는 우리 가 이전에 본 똑 같은 두 가지 요소, implementation 과 service 노드 가 있다.implementation 노드 는 구성 요 소 를 실현 하 는 클래스 의 이름 을 제공 합 니 다. service 노드 는 DS 에 게 서비스 처럼 이 구성 요 소 를 등록 하 라 고 알려 줍 니 다.이러한 상황 에서 우 리 는 CommandProvider 인터페이스 에 등록 합 니 다. 이것 은 우리 가 Equinox 콘 솔 에 우리 의 명령 제공 기 에 대한 존 재 를 알 리 는 방법 입 니 다.다음 노드 는 reference 라 고 하 는데 우리 가 이전에 본 적 이 없 는 것 입 니 다. DS 는 우리 의 구성 요소 가 서비스 에 의존 하고 있다 는 것 을 밝 혔 습 니 다.name 속성 은 의존 하 는 이름 의 임의의 문자열 일 뿐 입 니 다.bid 속성 은 서비스 가 유효 할 때 실 현 된 클래스 의 방법 이름 을 호출 합 니 다. 다시 말 하면 Runnable 서비스 가 Service Registry 로 등록 되면 DS 는 이 새로운 서비스의 인용 을 가 져 오고 이 지정 한 방법 으로 구성 요 소 를 제공 합 니 다.같은 unbid 속성 은 우리 가 사용 하 는 서비스 가 무효 가 될 때 DS 를 통 해 호출 하 는 것 입 니 다.Cardinality 속성 은 DS 의 진정한 강 함 을 보 여 줍 니 다.이 속성 은 이 의존 이 선택 할 수 있 거나 필요 한 지, 단독 또는 여러 개 인지 여 부 를 제어 합 니 다.가능 한 값 은:
원문 참조:
? 0. 1: 선택 가능 한 것 과 하나, "0 또는 1"?1. 1: 있 고 하나 밖 에 없어 요. '하나 밖 에 없어 요'?0. n: 여러 개 를 선택 할 수 있 습 니 다. "0 에서 많 습 니까?"1. n: 필요 하거나 여러 개, "0 에서 많 음" 또는 "적어도 하나"
이 예 에서 우 리 는 선택 할 수 있 는 것 과 하 나 를 선택 한 것 은 우리 의 명령 제공 자가 서비스 에 의존 하 는 것 이 무효 가 되 는 상황 에 대처 할 수 있다 는 것 을 의미한다.돌아 와 봐run 방법의 코드 입 니 다. null 을 검사 해 야 하 는 상황 을 볼 수 있 습 니 다.우리 가 이 Bundle 을 실행 하면 무슨 일이 일어 날 지 보 여 주세요.Simple Exporter Bundle 이 지난번 부터 계속 존재 한다 면 명령 행 프롬프트 osgi > "run" 을 입력 하면 다음 과 같은 응답 을 볼 수 있 습 니 다.
1
Hello from SampleRunnable

너무 좋아!이번 에는 지난 시간 에 우리 가 쓴 Runnable 서 비 스 를 성공 적 으로 도입 한 것 을 확정 했다.이제 "stop" 명령 을 사용 하여 SampleExporter 의 Bundle 을 닫 아 보 세 요."run" 명령 을 다시 입력 하면 다음 을 볼 수 있 습 니 다.
1
Error, no Runnable available

DS 알림 은 Runnable 서비스 가 사 라 졌 고 우리 의 unset Runnable 방법 을 사용 하여 우리 에 게 알려 주 었 다 는 뜻 입 니 다.cardinality 속성 을 다시 보 세 요. 만약 에 우리 가 '1. 1' 로 바 뀌 면 무슨 일이 일어 날 것 이 라 고 생각 합 니까? 예 를 들 어 선택 할 수 있 는 것 에서 필요 한 의존 으로 전환 하 는 것 입 니까?Equinox 를 바 꾸 고 다시 시작 해 보 세 요.SampleExporter 의 Bundle 이 활성화 되 어 있다 면 "run" 을 입력 하면 이전 과 같은 메시지 인 "Hello from SampleRunnable" 을 볼 수 있 습 니 다.그러나 SampleExporter 가 활성화 되 지 않 은 후에 우 리 는 이전 과 매우 다른 오류 정 보 를 볼 수 있 습 니 다.사실 Equinox 의 콘 솔 도움말 정 보 를 볼 수 있 습 니 다. 그것 은 인식 되 지 않 은 명령 에 대한 표준 응답 입 니 다.이것 은 우리 의 명령 이 다른 자신 을 제공 하 는 것 이 DS 를 통 해 취소 되 었 음 을 나타 낸다!구성 요소 가 필요 한 의존 이 있 을 때 까지 DS 는 제공 하 는 모든 서 비 스 를 취소 할 수 밖 에 없습니다.반대로 Equinox 콘 솔 은 'run' 명령 을 잊 어 버 렸 다.정책 속성 에 대해 이상 하 게 생각 할 수도 있 습 니 다. 아직 언급 하지 않 았 다 는 것 을 알 고 있 습 니 다.이 값 은 "static" 이나 "dynamic" 중의 하나 로 이 구성 요소 가 서비스의 동적 전환 에 대응 할 수 있 는 지 여 부 를 지적 합 니 다.동적 이 아니라면 대상 서비스 가 바 뀔 때마다 DS 구성 요 소 를 취소 하고 새로운 인 스 턴 스 를 만들어 야 합 니 다.원 하 시 는 바 와 같이 이것 은 중량급 의 방법 에 해당 합 니 다. 언제든지 가능 한 동적 전환 을 지원 하기 위해 구성 요 소 를 인 코딩 하 는 것 이 좋 습 니 다.불 행 히 도 기본 값 은 static 이 므 로 다이나믹 으로 명확 하 게 설정 하 는 것 을 기억 해 야 합 니 다.그렇다면 우 리 는 선택 할 수 있 는 단일 함 과 하나만 보 았 지만, 무엇이 다 중 의존 입 니까?Service Registry 에 하나 이상 의 Runnable 이 존재 할 수 있 습 니 다. 그리고 우리 가 그 중 하 나 를 연결 한 후에 선택 한 것 은 우리 가 얻 은 것 은 임 의 입 니 다.아마도 우 리 는 현재 등 록 된 모든 Runnable 을 실행 하기 위해 "runall" 명령 을 실행 하 는 것 을 좋아 할 것 입 니 다.만약 우리 가 cardinality 를 '0. n' 으로 바꾼다 면 무슨 일이 일어 날 까요?어떤 면 에 서 는 항상 작 동 합 니 다. setRunnable 방법 을 한 번 만 호출 하 는 대신 DS 는 모든 Registry 의 Runnable 인 스 턴 스 를 위해 setRunnable 을 한 번 호출 합 니 다.문 제 는 우리 가 쓴 종류 가 혼 란 스 러 울 것 이라는 것 이다.단독 Runnable 필드 를 설정 하 는 대신 Runnable 을 집합 에 저장 해 야 합 니 다.이 종류의 버 전 은 작은 변화 가 있 습 니 다. 프로젝트 의 src 폴 더 에 다시 복사 하고 붙 여 넣 을 것 입 니 다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package org.example.ds;
 
import java.util.*;
import org.eclipse.osgi.framework.console.CommandInterpreter;
import org.eclipse.osgi.framework.console.CommandProvider;
 
public class SampleCommandProvider2 implements CommandProvider {
 
	private List<Runnable> runnables =
		Collections.synchronizedList(new ArrayList<Runnable>());
	
	public void addRunnable(Runnable r) {
		runnables.add(r);
	}
	public void removeRunnable(Runnable r) {
		runnables.remove(r);
	}
	public void _runall(CommandInterpreter ci) {
		synchronized(runnables) {
			for(Runnable r : runnables) {
				r.run();
			}
		}
	}
	public String getHelp() {
		return "\trunall - Run all registered Runnables";
	}
}

현재 OSGI - INF / commandprovider 2. xml 를 만 들 고 다음 내용 을 복사 합 니 다.
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<component name="commandprovider2">
	<implementation class="org.example.ds.SampleCommandProvider2"/>
	<service>
		<provide interface="org.eclipse.osgi.framework.console.CommandProvider"/>
	</service>
	<reference name="RUNNABLE"
		interface="java.lang.Runnable"
		bind="addRunnable"
		unbind="removeRunnable"
		cardinality="0..n"
		policy="dynamic"/>
</component>

마지막 으로 이 파일 을 manifest 의 service - coponent 머리 에 추가 합 니 다. 이렇게 보 입 니 다.
1
2
Service-Component: OSGI-INF/commandprovider1.xml,
  OSGI-INF/commandprovider2.xml

이 성명 은 이전 과 마찬가지 로 우리 가 bind 와 unbind 방법 에 대해 이름 을 바 꾸 고 cardinality 를 '0. n' 으로 바 꾸 는 것 을 제외 하고 없어 서 는 안 됩 니 다.연습 처럼 추가 적 인 Runnable 서 비 스 를 등록 하고 'runall' 명령 이 모두 실행 되 는 지 확인 해 보 세 요.다음 에 우리 가 cardinality 를 '1. n' 으로 바 꾸 면 무슨 일이 일어 날 것 같 습 니까?당신 의 상상 을 검증 해 보 세 요.That's all for this lesson. Remember that the OSGi Alliance Community Event is happening next week in Munich, Germany, and I believe it's still not too late to register . See you there!

좋은 웹페이지 즐겨찾기