OSGI
Eclipse 3.0后采用的是OSGI来作为其Plugin Architecture实现的依据,鉴于此就得简单提提OSGI了,主要从Plugin的角度来分析OSGIQOSGI概念中主要分ZBundle和ServiceQ可以认为Bundle是一个模块的理器,主要是通过BundleActivator理模块的生命周期,而Service则是q个模块可暴露对外的服务对象Q这里体COSGI和传l的Plugin Framework不同的一个地方,理和静态结构分开Q在OSGI中通过在manifest.mf文g中增加一些内Ҏ发布BundleQ在其中描述了Bundle的提供商、版本、唯一ID、classpath、暴露对外的包、所依赖的包Q每个Bundle拥有自己的ClassLoader以及contextQ通过context可进行服务的注册、卸载等Q这些操作都会通过事g机制q播l相应的其他的BundleQ一般来说都为通过在Bundle中编写初始需要注册的服务的方法来完成Bundle可供外部使用的服务的暴露功能Q如需要调用其他Plugin提供的服务可通过context的getServiceReference先获取Service的句柄,再通过context.getService(ServiceReference)的方法获取Service的实体?/P>
Eclipse Plugin定义
Eclipse中的Plugin的概念ؓ包含一pd服务的模块即Z个Plugin。既然是遵@OSGI的,也就意味着Plugin通常是由Bundle和N多Service共同构成的,在此基础上Eclipse认ؓPlugin之间通常存在两种关系Q一Uؓ依赖Q一Uؓ扩展Q对于依赖可通过OSGI中元描述信息里添加需要引用的Plugin卛_实现Q但扩展在OSGI中是没有定义的,Eclipse采用了一个Extension Point的方式来实现Plugin的扩展功能?BR>l合OSGI
Eclipse遵@OSGI对于Plugin的ID、版本、提供商、classpath、所依赖的plugin以及可暴露对外的包均在manifest.mf文g中定义?BR>Plugin Extension Point
对于扩展QEclipse采用Extension Point的方式来实现Q每个Plugin可定义自qExtension PointQ同时也可实现其他Plugin的Extension PointQ由于这个在OSGI中是未定义的Q在Eclipse中仍焉过在plugin.xml中进行描qͼ描述的方法ؓ通过<extension-point id="" name="" schema="">的Ş式来定义Plugin的扩展点Q通过<extension point="">的Ş式来定义实现的其他Plugin的扩展点Q所提供的扩展点通过schema的方式进行描qͼ详细见eclipse extension-point schema规范Qؓ了更好的说明扩展点这个概念,举例如下Q如工具栏就是工hPlugin提供的一个扩展点Q其他的Plugin可通过此扩展点d按钮臛_h中,q可相应的添加按钮所对应的事?当然Q此事g必须实现工具栏Plugin此扩展点所要求的接?Q工h的Plugin通过callback的方式来相应的响应按钮的动作。可见通过Extension Point的方式可以很好的提供Plugin的扩展方式以及实现扩展的方式?/P>
Eclipse Plugin Framework
那么Eclipse是如何做到Plugin机制的实现的呢?Q还是先讲讲Eclipse的设计风|Eclipse在设计时有个重要的分层法则,卌a层相兛_语言层无关的代码分开(如jdt.core和core)Q核心与UI分开(如workbench.ui和workbench.core)q两个分层法则,q个在Eclipse代码中处处可见,在Plugin Framework部分也充分得体现了这个,遵@OSGIQEclipse首先是实C一个OSGI ImplQ这个主要通过它的FrameWork、BundleHost、ServiceRegistry、BundleContextImpl{对象来实现Q如果关心的话大家可以看看这部分的代码,实现了Bundle的安装、触发、卸载以及Service的注册、卸载、调用,在Plugin机制上Eclipse采用的ؓlazy load的方式,卛_调用时才q行实际的启动,采用的ؓ句柄/实体的方式来实现Q外部则通过OSGIq行启动、停止等动作Q各Plugin则通过BundleContext来进行服务的注册、卸载和调用Q这是OSGI的部分实现的单介l?BR>那么Extension Point斚wEclipse是如何实现的呢,在加载PluginӞEclipse通过对plugin.xml的解析获取其中的<extension-point>节点?lt;extension>节点Qƈ相应的注册到ExtensionRegistry中,而各个提供扩展点的Plugin在提供扩展点的地方进行处理,如工hPlugin提供了工h的扩展点Q那么在构成工具栏时Plugin通过Platform.getPluginRegistry().getExtensionPoint(扩展点ID)的方法获取所有实现此扩展点的集合IExtensionPoint[]Q通过此集合可获取IConfigurationElement[]Q而通过q个可以获?lt;extension point="">其中的配|,同时q可通过IConfigurationElement创徏回调对象的实例,通过q样的方法Eclipse也就实现了对于Plugin的扩展以及扩展的功能的回调。在Plugin Framework中还涉及很多事g机制的用,比如Framework的事件机Ӟ以便在Bundle注册、Service注册的时候进行通知?/P>
ȝ
通过对Eclipse启动q程的分析,可清晰的看到Eclipse Kernel+Core Plugins+Application Plugins的方式,在代码中分别对应为loadBasicBundles和registerApplicationServicesQloadBasicBundles通过加蝲config.ini中的osgi.bundles完成基本的bundles的加载,ȝ看这个配|会发现是org.eclipse.core.runtimeq有一个updateQcore.runtime又会通过IDEApplication来完成整个Eclipse的启动,同时会注册所有与workbench相关的plugin?BR>Eclipse׃以前版本的Plugin Framework是没有采用OSGI的,所以通过EclipseAdaptor的方式来实现与以往的兼容,目前新的Plugin采用的方式基本就是manifest.mf描述Plugin OSGI部分的信息,Plugin.xml描述扩展点的信息?BR>Eclipse中有非常多优U的设计,q个在看它的代码时会有很q感触Q比如Contributing to Eclipse中提到的Extension Object/Interface的设计,实是非常的不错Q虽然看C可能觉得很简单,关键是要惛_到ƈ合适的M用?BR>ȝ陈词Q^_^QEclipse Plugin Framework是采用OSGI Impl+Plugin Extension-Point的方式来共同实现的,实现了Plugin的部|Ӏ编写、独立的Classloader和Context、Plugin中Service的注册、Plugin中Service的调用、Plugin的依赖、Plugin的扩展、Plugin生命周期的管理?/P>
带来的思?BR>Eclipse Plugin Framework采用的是OSGI的实玎ͼ一定程度上我们也能看到OSGI的优点,那么JMX+IoC方式的Plugin Framework与其的比较又是在哪些斚w呢?Eclipse Plugin Framework不的地方又在哪里呢Q哪些地方值得改进呢?