【原创】插件开发入门 (十五)
上一篇 / 下一篇 2008-07-01 16:41:21 / 个人分类:Eclipse插件开发
Eclipse最有魅力的地方就是它的插件体系结构。在这个体系中重要的概念是扩展点(extension points)。扩展点就是在软件开发过程中暴露出来的接口。每一个插件都是在现有的扩展点上开发的,并可能还留有自己的扩展点,以便在这个插件上继续开发。
~4M%s+gOKD
y0
Y_X\+F0简介
ITPUB个人空间7c0R'j_4x]Bk
Eclipse 平台是IBM向开发源码社区捐赠的开发框架,它之所以出名并不是因为IBM宣称投入开发的资金总数为4 000万美元,而是因为如此巨大的投入所带来的成果:一个成熟的、精心设计的、可扩展的体系结构。Eclipse 的价值是它为创建可扩展的集成开发环境提供了一个开放源码平台。这个平台允许任何人构建与环境和其他工具无缝集成的工具。工具与Eclipse无缝集成的关键是插件。除了小型的运行时内核之外,Eclipse中的所有东西都是插件。从这个角度来讲,所有功能部件都是以同等的方式创建的。
-I,E3vP!Fx7{ mn0
|IsCb.p0由于有了插件,Eclipse系统的核心部分在启动时要完成的工作十分简单:启动平台的基础部分和查找系统的插件。整个Eclipse体系结构就像一个大拼图,可以不断地向上加插件,同时,在现有插件上还可以再加插件。ITPUB个人空间%pT%{YhO
"{U pJ y p#c5a*G0开发“Hello,world”插件
ITPUB个人空间M6s7Ec)NDz4K%j
创建插件最简单的方法是使用Eclipse中专门为开发插件而设计的插件PDE(Plug-in Development Environment)。PDE 和 Java Development Tooling(JDT)IDE是 Eclipse 的标准扩展。PDE 提供了一些向导可以帮助创建插件。下面的“Hello,world”插件将通过PDE进行开发。ITPUB个人空间?kK5o$i$M'hC{:^
:jXv,o5Q,z;h6l,P L0下面是创建一个简单插件的操作步骤。ITPUB个人空间y
Gp3DQ:lY
ITPUB个人空间T(g A}(A)IT X
(1)运行Eclipse。ITPUB个人空间@3Ocn)ved1P
ITPUB个人空间1FyuOY6Le0_*__
单击Eclipse的“File”→“New”→“Other”菜单项,在弹出的对话框中选择Select对话框左边的Plug-in Development向导。如图1所示,选择Plug-in Project。
{R*W0t/U+F0ITPUB个人空间!`&H&dGh2I"J
ITPUB个人空间
m&N$h1iq
B3~"l
图1 新建插件对话框
D%~
jS2Q3m%XG0ITPUB个人空间)Q.lKsU0^[
(2)单击“Next”按钮,弹出新建对话框,输入项目名称。此处使用了“com.test.helloworld”。单击“Next”按钮后弹出新建对话框页,如图2所示,插件标识就与项目名称相同。使用项目名称作为插件标识可以将该插件与另一个插件的名称发生冲突的机会减到最小。
A5T
tw1Vn4J+_h0
"XF+Tz*@Pc0
Y8PWQ%L2vP v%v0图2 新建对话框向导ITPUB个人空间nn\Q*?6F
ITPUB个人空间4C:qE
aF
(3)单击“Next”按钮,选择“Hello, world”,如图3所示。ITPUB个人空间6_]2I{;`)U^Ok8d
Y\!?~9Td/g:wBn0
ITPUB个人空间~c/K3tT;r$Z*C
U:{
图3 新建插件向导
yB9lR.Ht|8K!JXN0ITPUB个人空间vKH*wb7hn_*T
(4)单击“Finish”按钮,就可以创建用户想要建立的插件。ITPUB个人空间H m.D
YJ
jw2~o$Z(}&Tt0上例中通过插件创建向导创建了“Hello,world插件”,通过Eclipse的插件创建向导还能够创建其它扩展点插件的创建。
~K&bT5a1it0
Q7P
[ [Ws0调试“Hello,world”插件
'VZ;r(|h;j4Lk0通过PDE不但能创建插件,还能够调试插件。在Eclipse中调试插件的步骤如下。
G(_.cs4yA0
~
A_ kj,mm3k0(1)单击“Run”→“Debug”菜单项。ITPUB个人空间!FWy&r%P\%\
E1y*qI/@s0G0(2)在弹出的对话框窗口中用鼠标右键单击“Eclipse Application”选项。ITPUB个人空间"pS)YCN?{$@[5I
ITPUB个人空间T-wV.rT
kl0a
(3)单击“New”菜单项(或双击Eclipse Application树节点),创建调试插件配置参数对话框,并通过对话框设置插件的调试参数,如图4所示。ITPUB个人空间om7`
E8JpL;]q
ITPUB个人空间;x3@6W1@/o7R
ITPUB个人空间t2N$qMtf-k
图4 Debug环境参数设置ITPUB个人空间i4] mfuZ!BP?
ITPUB个人空间-bVg)OYo$V%X
(4)单击“Debug”按钮。
t0Wo6W
wL:u#e0ITPUB个人空间#R1w7E$D/Cm'L
现在已经启动了一个调试的Eclipse,可以看到图5显示的调试窗口。调试窗口多了一个“Sample Menu”菜单项,工具栏多了一个按钮,单击菜单或按钮将会弹出 “Hello,world”对话框。
u*ou0gqu n/I U0
!{g#? e2f
zZ0
8XP;z+n6dF7jVov0图5 “Hello,world”插件效果图
w4V3I,Zu,c0
%d+~9M-y6[$st9{~ VH*a0用户可以在程序中可执行到的位置设置断点,就可以和调试Java程序一样调试Eclipse插件了。ITPUB个人空间^K1\(X)O(K
w%b2Wo/eo+h[0注意:如果在图4中选择Clear workspace data before lauching,表示每次调试插件时是否提示清空运行时刻的Workspace。可以选择“是”,表示重建运行时刻的Workspace。ITPUB个人空间6Bug9Sy0l%}U
w
ske+q[+G9O"N0插件打包
^/z7i
`$]3_/H0这一步是把用户开发的插件打包,供别人使用。具体步骤如下。
z.f)m3e Kl_m0
Eu:I$?9|
yh){o0(1)选择“Hello,world”插件,单击鼠标右键,选择“Export”菜单,弹出图6所示的对话框。ITPUB个人空间m&]
r9nN*P;V8@`R
u0C
9Q2U,~@eZ&hf0
Jj1O$g[+`0`]0图6 插件打包对话框
3vl1M;@(ZI|l~0
,d?\#h2Z4F!a+q0(2)输入用户想要打包的文件名。如果想把源文件也打包,可以选择“Include source code”复选框。现在“Hello,world”插件就已经成功打包了。ITPUB个人空间9R*CxfFu
|Y!BH7m3]1C f
l0(3)把“Hello,world”插件解压缩拷贝到用户的Eclipse的Plugins目录下面。运行Eclipse,就可以在运行环境下看到“Hello,world”插件的身影了。ITPUB个人空间(cN6qfBX
0Oc qcr$s0通过Export 菜单对插件进行打包,实际上Eclipse会读取插件目录下的build.properties文件,通过它来描述需要打包的内容。
c'F1jWbmQ*n0
*jGt^J&C
l0提示:不要把“Hello,World”插件拷贝到开发环境的Eclipse下面,否则插件可能不会被注册。因为开发环境的Workspace中有相同ID的插件,这样会产生冲突。要养成好习惯,把开发环境和部署环境分开。ITPUB个人空间&T| l;P$GV)p+O
7F6rH6C4T5U\!@0插件描述文件
u/dD'vQG3I0Eclipse中插件的描术文件包括Plugin.xml文件和MANIFEST.MF:ITPUB个人空间vW-qHu
ITPUB个人空间ipF N:b
l Plugin.xml:Plugin.xml描述了扩展点的基本信息,包括扩展点的实现和定义,它按照扩展点的定义文件(schema)描述扩展的信息。
-A-mXt"w0
vk k:K|6~TA OP0l MANIFEST.MF:MANIFEST.MF记录了插件的状态信息,包括插件的依赖关系、运行时的类加载路径以及插件的名称等。
hAJM!W0
~U@~i7q/B1c0Plugin.xml主要是通过XML文件格式描述扩展点的具体内容。当Eclipse启动后,它将会找到所有插件的描述文件。当Eclipse第一次启动某一个插件时,它会从MANIFEST.MF文件读取插件的相关信息,并通过定义的插件类初始化插件。
1b6['rM/pKeUv0
[ E:Mj{!I4d)Q0插件描述文件编辑器窗口,如图7所示。
O
Raa jx0ITPUB个人空间ycW;}I#_m7_k&z
ITPUB个人空间9U{!L e{D6k ?f
图7 清单文件编辑窗口ITPUB个人空间_
z4s!bO
ITPUB个人空间Q%jGb0|&Ze
Manifest.MF文件中保存了插件的基本信息(和OSGI相关的信息),而Plugin.xml文件记录了扩展点的信息,这两个文件在一个编辑器中展现,分成如下几个部分。ITPUB个人空间[E I,lU:Rr
ITPUB个人空间7or"z4DH2WV%psU
l Overview:描述了插件的基本信息。ITPUB个人空间
[i
y#j2Za
ITPUB个人空间 y:o
^}a`-XaN
l Dependencies:描述了插件的依赖关系。ITPUB个人空间7}}dP7j
ED }%|#E0l Runtime:指明运行时的ClassPath。
s]#O4[P
a0ITPUB个人空间Jx4h7e1b
l Extensions:指明插件实现的扩展点。
4]6bI a(Y1X+O0
,I:y3{a9^/fy;G0l Extension Points:指明插件提供的扩展点。
!w
tVa"ez!zt"L0
"VB.h3u0R3?01. OverView:描述了插件的基本信息
lr(jg dy0
o4WQ8I+Kr)x;WY0OverView描述了插件的基本信息,如图8所示。
@+z/JS8A;{,J$o m,i0ITPUB个人空间"c|-qY#Q{-K$zPl
ITPUB个人空间w3Y!imP?[+e
图8 OverView页面
,oRsv M`j0ITPUB个人空间 d]
n3|t4dh
l ID:ID是插件的ID号,在Eclipse中是一个具体标识。
9^$a-g:} Jn/y0
9{KH1gp~2l/h/X0l Version:Version指明用户所开发的插件的版本号。
-hm_o Yq4l0ITPUB个人空间1Ge7~I2a
l Name:指用户所开发的插件的名称。
%|(X!ot'r0K#w uaW0
6A#]q;y^0l Provider:开发者。
L5?W!C8S7a3W7M0
8`$hGy%Yq5apzkyD0l Class:Class是指插件类,它由Eclipse建立并初始化,后面的章节将会详细介绍。ITPUB个人空间~0s,U$MC/jy&lR
+y eFoI0l Platform. Filter:指定平台相关的一些信息,一般来说用户不需要设定。ITPUB个人空间weYZ/j!N)h$HjI s
3a%p#|C?QJ"z.f+M#qE0提示:ID号在Eclipse中是一个全局的标识。很多初学者常常会对不同的插件命名成相同的ID号,这样会导致插件不能加载。
`/D5_B6n+eRs0
M$v#j7L)ea6]02. Dependencies:描述了插件的依赖关系ITPUB个人空间fr'mB5_!kGA&b X.Lt
?p4I-{8[3hvt0Dependencies页面描述了插件的依赖关系,如图9所示,插件依赖org.eclipse.ui和org.eclipse.core.runtime插件。ITPUB个人空间i3g"wg8e)i0tXX
ITPUB个人空间
E
f4qI+O#L
YM,K O:T)K0图9 Dependencies页面
)U6G a/^x,s#cw&B0ITPUB个人空间o_MMM
M)Jvd
Dependencies是一个比较重要的概念。每一个插件有独立的ClassPath,Dependencies会把依赖的插件的ClassPath加入到当前的ClassPath中。
C"D"Ut\D+R0
D%B:Jqq
w JJ0提示:插件可以调用依赖的插件中所有导出的类,但插件不能够有循环依赖,所以在设计插件的结构时一定要设计合理,切记、切记。
[1a"|L5@Ri0ITPUB个人空间+I
e9Y
kHd,F'j
3. Runtime:指明了运行时的ClassPathITPUB个人空间.c7BAQ`&vyk"zye
ITPUB个人空间}
b{*F2ptu
Runtime:指明了运行时的ClassPath。如图10所示,jdom.jar为此插件运行时依赖的包。
(GT*@/Xc
Oj&Z0
Y`/W/w Uh*M ~0
pIhz&pgGzv0图10 Runtime页面
XirwQ:PE5U0
F#Gl"yv[;U0在Exported packages中也加入了一些要导出的包,如果不导出这些包,其它依赖当前插件的插件就用不了当前插件中对应包下的类。ITPUB个人空间)p$ea
smuW C!u4\a
tzF1|)y0Runtime也是一个比较重要的概念,它指明了运行时的环境。Eclipse中插件不会引用到系统的ClassPath,每一个插件都有独立的ClassPath。ITPUB个人空间$s_ nk/d"J
ITPUB个人空间7i
w'M~%qyd
提示:很多人在开发插件时,没有通过Runtime指明ClassPath,而是直接添加Jar包,这样,在编译期间可能不会出错,但是在插件运行时会提示类找不到(ClassNotFoundException),就是这个问题。
;g$u&F&A/v:l0Nqe;V3eH0ITPUB个人空间CIPN5fbf\H
4. Extensions:指明插件实现的扩展点
9q[2H:OpOCT K0
/XGJ?pP}ISH*U0Extensions:指明插件实现的扩展点。例如插件要实现“org.eclipse.ui.actionSets”扩展点,如图11所示。ITPUB个人空间
b
n+[V5G;Rk
:J.C
d9\%@]w0
y3ca,X!nS4? c$K0图11 Extensions页面
A&p3R&v$[-mu0ITPUB个人空间{iI`!u;Y(Yv&O@ @
Extensions是用户在开发一个插件中用到的扩展点,也是Eclipse开发的精髓所在。后面章节的主要工作就是围绕扩展点展开的。下面为扩展点在Plugin.xml文件中定义的片段。ITPUB个人空间aR'BT
Uzw
QG6?a
ITPUB个人空间Ob.rJ)`%|.xN
<!-- 实现的扩展点 -->ITPUB个人空间YA {)~/@0l
"s3l*o uTct6R_0<extension
QTYjVb_0ITPUB个人空间D"|;x
M%i2n0v&D
point="org.eclipse.ui.actionSets">
W)V;^\$uc5d-w~A._0
{\[IB/fM0<actionSet
y/H*eF7^'S+K0H0ITPUB个人空间"heMqO7n'|OR
label="Sample Action Set"
|dM0Z8K0ITPUB个人空间K}vA2L R1?6y2U2?e1m
visible="true"ITPUB个人空间/}_K^Zf.jX)l]/j
ITPUB个人空间D*[gxX@TC:Xc
id="com.test.helloworld.actionSet">ITPUB个人空间j&k