동적 플러그인은 실행 중인 Eclipse 인스턴스에 플러그인을 삽입하고 제거하는 기능을 제공합니다. 로드 해제될 수 있는 재사용 가능한 컴포넌트인 동적 플러그인을 사용하면 들어오고 나가는 플러그인을 쉽게 추적할 수 있습니다.
동적 플러그인은 응용프로그램의 주기 중에 남아 있지 않을 수 있습니다. 응용프로그램에 있어서 컴포넌트가 제거되었을 때 모든 것이 정리되도록 하는 것이 필수적입니다. 리스너가 Workbench에 연결되고 항목이 등록되면 리스너와 항목은 시스템 종료 후에도 남아 있고 이러한 플러그인은 이러한 리스너와 항목을 정리해야 함을 인식해야 합니다.
시작에서 확장점의 모든 구현에 대한 충분한 읽기가 응용프로그램의 주기를 이해하는 데 충분하다는 가정은 올바르지 않습니다. 리스너가 연결되는지 또는 아무 것도 이용되지 않는지 확인하여 레지스트리 변경사항이 청취되도록 해야 합니다. Workbench의 항목은 정적일 필요는 없고 실제로 임시적이고 언제라도 제거할 수 있음을 이해하는 것이 중요합니다. 특정 보기에 대한 플러그인을 쓰고 있는 경우에는 먼저 보기가 계속 존재하는지 확인하십시오.
플러그인 개발자는 활용하는 모든 확장이 지정된 확장점에 나타나거나 사라질 수 있도록 허용해야 합니다. 확장이 사라질 경우 확장을 나타내는 모든 내부 구조를 정리하여 확장이 사라졌음을 확인하고 확장이 드라이브하는 모든 UI 아티팩트를 제거해야 합니다. 확장이 나타날 경우 내부 구조를 확장하고 새 UI 아티팩트를 작성해야 합니다. 응용프로그램이 레지스트리를 읽는 중이고 확장을 가지며 응용프로그램에 대한 레코드가 작성되고 위치가 지정된다고 가정해 보십시오. 결과에 따라 정리가 필요한지 알리는 메시지가 표시됩니다. 또한 리스너는 새 항목이 들어올 경우 이를 알리고 해당 항목을 작성합니다.
org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker 및 연관된 인터페이스는 플러그인 개발자가 들어오고 나가는 확장을 쉽게 추적하고 해당 조치에 의해 생성된 자원을 관리할 수 있는 메커니즘을 제공합니다.
다음 예제에서는 플러그인에 위지트(widget)라고 하는 확장점이 있고 IExtensionTracker를 사용 중임을 가정합니다. 내부적으로 위지트(widget) 확장을 캡슐화한 WidgetDescriptor 및 이들을 관리하는 WidgetRegistry가 있습니다.
public class WidgetRegistry implements IExtensionChangeHandler { public WidgetRegistry() { IExtensionTracker tracker = PlatformUI.getWorkbench() .getExtensionTracker();
IExtensionPoint point = Platform.getExtensionRegistry() .getExtensionPoint("my.plugin.namespace", "widget");
IExtension[] extensions = point.getExtensions();
// initial population
for (int i = 0; i < extensions.length; i++) { addExtension(tracker, extensions[i]);
} tracker
.registerHandler(this, tracker
.createExtensionPointFilter(point)); } public void addExtension(IExtensionTracker tracker, IExtension extension){ WidgetDescriptor descriptor = new WidgetDescriptor(extension); tracker.registerObject(extension, descriptor,
IExtensionTracker.REF_STRONG); addToInternalStructure(descriptor) } private void addToInternalStructure(WidgetDescriptor descriptor) { // registry specific logic } public void removeExtension(IExtension extension, Object[] objects) { for (int i = 0; i < objects.length; i++) { WidgetDescriptor descriptor = (WidgetDescriptor) objects[i];
removeFromInternalStructure(descriptor);
}
} private void removeFromInternalStructure(WidgetDescriptor descriptor) { // registry specific logic }
} public void dispose() { PlatformUI.getWorkbench() .getExtensionTracker().unregisterHandler(this)
} }
이 예제에서 Platform UI는 다양한 Workbench 레벨에서 IExtensionTracker 인스턴스를 제공합니다. Workbench 주기에서 활성 상태인 오브젝트를 추적하려면 Workbench.getExtensionTracker()가 제공하는 추적자를 사용해야 합니다. 해당 오브젝트가 특정 Workbench 창 또는 페이지에 관련된 경우에는 IWorkbenchWindow.getExtensionTracker() 또는 IWorkbenchPage.getExtensionTracker()가 제공하는 추적자를 사용해야 합니다. 예를 들어 Workbench는 보기 설명자를 Workbench 레벨에서 추적하지만 실제 보기 인스턴스를 Workbench 페이지 레벨에서 추적합니다. IFilter 인스턴스를 IExtensionTracker.registerHandler()에 제공하여 특정 확장점에 대해 핸들러를 등록할 수도 있습니다. 핸들러는 IFilter 오브젝트와 일치하는 확장을 추가 또는 제거할 때만 호출됩니다.
확장이 런타임에 입력될 때 이 메소드가 호출됩니다. 그런 다음 핸들러는 새 확장을 연관된 모델로 통합할 수 있습니다. 이 인터페이스에 제공된 IExtension을 기반으로 작성된 오브젝트는 IExtensionTracker.registerObject()를 통해 추적자에 대해 등록해야 합니다. 확장이 런타임에서 나가게 되면 이 메소드가 호출됩니다. 해당 확장에 대해 이전에 등록한 오브젝트는 인수로 전달됩니다. 그런 다음 핸들러는 필요에 따라 오브젝트를 정리 및 처리합니다. 레지스트리가 누출되지 않도록 핸들러를 등록 해제하는 것이 좋습니다.