【原创】插件开发入门 (十五)
上一篇 / 下一篇 2008-07-01 16:41:21 / 个人分类:Eclipse插件开发
Eclipse最有魅力的地方就是它的插件体系结构。在这个体系中重要的概念是扩展点(extension points)。扩展点就是在软件开发过程中暴露出来的接口。每一个插件都是在现有的扩展点上开发的,并可能还留有自己的扩展点,以便在这个插件上继续开发。ITPUB个人空间UFx/i{M
-DoR[M7y0简介
ITPUB个人空间"V#CiwH1T
Eclipse 平台是IBM向开发源码社区捐赠的开发框架,它之所以出名并不是因为IBM宣称投入开发的资金总数为4 000万美元,而是因为如此巨大的投入所带来的成果:一个成熟的、精心设计的、可扩展的体系结构。Eclipse 的价值是它为创建可扩展的集成开发环境提供了一个开放源码平台。这个平台允许任何人构建与环境和其他工具无缝集成的工具。工具与Eclipse无缝集成的关键是插件。除了小型的运行时内核之外,Eclipse中的所有东西都是插件。从这个角度来讲,所有功能部件都是以同等的方式创建的。ITPUB个人空间kK8}J@x$r"Xa
h?r6?\+I,A1O0由于有了插件,Eclipse系统的核心部分在启动时要完成的工作十分简单:启动平台的基础部分和查找系统的插件。整个Eclipse体系结构就像一个大拼图,可以不断地向上加插件,同时,在现有插件上还可以再加插件。
1LSp K si'I5Tu[0^0ITPUB个人空间5_)Y9_h~.~4J
开发“Hello,world”插件
:B8_&V ['}z&j#S0创建插件最简单的方法是使用Eclipse中专门为开发插件而设计的插件PDE(Plug-in Development Environment)。PDE 和 Java Development Tooling(JDT)IDE是 Eclipse 的标准扩展。PDE 提供了一些向导可以帮助创建插件。下面的“Hello,world”插件将通过PDE进行开发。
LQ9Z[+qX0
vI
b6vZ1]
E`;^0下面是创建一个简单插件的操作步骤。
^|)z|}^0
r9|rQ-{
["n,N0(1)运行Eclipse。ITPUB个人空间_ _!`$V
@d)lm,w
ITPUB个人空间*w!gk8c*s$L)H
单击Eclipse的“File”→“New”→“Other”菜单项,在弹出的对话框中选择Select对话框左边的Plug-in Development向导。如图1所示,选择Plug-in Project。ITPUB个人空间2F [/dI
_2CH3E|OV
0yhU8h
XTv*E.U@#O0图1 新建插件对话框ITPUB个人空间:]Ee zA$R@e X
8h%C"} TZ0(2)单击“Next”按钮,弹出新建对话框,输入项目名称。此处使用了“com.test.helloworld”。单击“Next”按钮后弹出新建对话框页,如图2所示,插件标识就与项目名称相同。使用项目名称作为插件标识可以将该插件与另一个插件的名称发生冲突的机会减到最小。ITPUB个人空间alN;KQ8SP
`
ITPUB个人空间+n8GJe+n7`']
ITPUB个人空间\@
["J4U*|
图2 新建对话框向导
U1N,cnn0ITPUB个人空间^r7|1F`0Q!ac
(3)单击“Next”按钮,选择“Hello, world”,如图3所示。ITPUB个人空间
_ o-f/}4Vf
|0gqRgZk-F fb0
g%ubT
W3|0图3 新建插件向导
$rZ(z&j9M1x xe3h#Ek0
0H.hCY0F*]~+Y0(4)单击“Finish”按钮,就可以创建用户想要建立的插件。ITPUB个人空间3q.Q3qG-c
ITPUB个人空间7}&M7X9tj.H K
ik"d9O
上例中通过插件创建向导创建了“Hello,world插件”,通过Eclipse的插件创建向导还能够创建其它扩展点插件的创建。ITPUB个人空间5H)xx+\*a6li2y
ITPUB个人空间4}!E g$h+hG,|8V
调试“Hello,world”插件
ITPUB个人空间{x-D_D.h0W"D~5CJ
通过PDE不但能创建插件,还能够调试插件。在Eclipse中调试插件的步骤如下。ITPUB个人空间i-q0{'Op8t)Wq8o
$O3f2e
q)hGa4d0(1)单击“Run”→“Debug”菜单项。
LDP
~,j-{#K,s0ITPUB个人空间2u"d
CK+s9K.Jnc
(2)在弹出的对话框窗口中用鼠标右键单击“Eclipse Application”选项。ITPUB个人空间 o5w+Lm;Z2H0e
#@m,E[ wY0(3)单击“New”菜单项(或双击Eclipse Application树节点),创建调试插件配置参数对话框,并通过对话框设置插件的调试参数,如图4所示。
X8t1gO W F
tC3J0
ITPUB个人空间-P6Lm$e:A pke
,a!e*Z0~O?UZ0图4 Debug环境参数设置ITPUB个人空间+i+P;{;p9]*@c
ITPUB个人空间'z'^ wo)e uq8k}z
(4)单击“Debug”按钮。ITPUB个人空间YQ/j:Hn2Z|
-z}+c&nR[b0现在已经启动了一个调试的Eclipse,可以看到图5显示的调试窗口。调试窗口多了一个“Sample Menu”菜单项,工具栏多了一个按钮,单击菜单或按钮将会弹出 “Hello,world”对话框。
-T1BQRN(K0
ITPUB个人空间
zDUR!y+^ M
vRUd"u0图5 “Hello,world”插件效果图
h
}/@%A RD6D(C0ITPUB个人空间X"r[9m7@
用户可以在程序中可执行到的位置设置断点,就可以和调试Java程序一样调试Eclipse插件了。ITPUB个人空间!v6I*^!OEW;w1v
ITPUB个人空间tj4z2^CS,S
注意:如果在图4中选择Clear workspace data before lauching,表示每次调试插件时是否提示清空运行时刻的Workspace。可以选择“是”,表示重建运行时刻的Workspace。ITPUB个人空间q8dM zJ
ITPUB个人空间#L9i1l
V8O%NHr:`0rz1i
插件打包
ITPUB个人空间vRob6z
这一步是把用户开发的插件打包,供别人使用。具体步骤如下。ITPUB个人空间 C)sU'y`9rKUs_D3@
ITPUB个人空间KkP%G;Q
B5EZ;q
(1)选择“Hello,world”插件,单击鼠标右键,选择“Export”菜单,弹出图6所示的对话框。ITPUB个人空间&I(|,k]j0B.o
UV4Rb1M7O'N@pv0
Y%r'y"DrNh0图6 插件打包对话框
dC;W1h%v0ITPUB个人空间7j$v[s"K2Y.R4E4c
(2)输入用户想要打包的文件名。如果想把源文件也打包,可以选择“Include source code”复选框。现在“Hello,world”插件就已经成功打包了。
z`u9yEQ uy"H,?)c0
6e$s8k$g?3gP{
kM^L0(3)把“Hello,world”插件解压缩拷贝到用户的Eclipse的Plugins目录下面。运行Eclipse,就可以在运行环境下看到“Hello,world”插件的身影了。ITPUB个人空间P
iFqX!Z
ITPUB个人空间4sq3}EW{2t
通过Export 菜单对插件进行打包,实际上Eclipse会读取插件目录下的build.properties文件,通过它来描述需要打包的内容。ITPUB个人空间9?-vG$k
t
ITPUB个人空间jW]K.]4m@V
提示:不要把“Hello,World”插件拷贝到开发环境的Eclipse下面,否则插件可能不会被注册。因为开发环境的Workspace中有相同ID的插件,这样会产生冲突。要养成好习惯,把开发环境和部署环境分开。
p)]7k4z
s2eT-o0
Z0yK i^9~ Nb0插件描述文件
3j m(^!a*k0Eclipse中插件的描术文件包括Plugin.xml文件和MANIFEST.MF:
]8B } QYB.MRl0
R5Z V2k;M0o hW0l Plugin.xml:Plugin.xml描述了扩展点的基本信息,包括扩展点的实现和定义,它按照扩展点的定义文件(schema)描述扩展的信息。ITPUB个人空间MCy(`,v,S
ed X
ITPUB个人空间 M~/u.h/O6?%Jy
l MANIFEST.MF:MANIFEST.MF记录了插件的状态信息,包括插件的依赖关系、运行时的类加载路径以及插件的名称等。ITPUB个人空间(Br!Fc7i:W3v
Qv&[5mkId0Plugin.xml主要是通过XML文件格式描述扩展点的具体内容。当Eclipse启动后,它将会找到所有插件的描述文件。当Eclipse第一次启动某一个插件时,它会从MANIFEST.MF文件读取插件的相关信息,并通过定义的插件类初始化插件。
sq PYR-c@;W0ITPUB个人空间/@;g)E%t l0D Z
插件描述文件编辑器窗口,如图7所示。
y$c
iaY6iU0
tO`:y)op0
*M1Lj7e]&N
U;v0图7 清单文件编辑窗口
,X3\PA9k*KR
`+M^0ITPUB个人空间Q6{#s4K)_[
A6I
Manifest.MF文件中保存了插件的基本信息(和OSGI相关的信息),而Plugin.xml文件记录了扩展点的信息,这两个文件在一个编辑器中展现,分成如下几个部分。ITPUB个人空间C;HOt@8l.}(D2?@
4l5NF0S:P*N$Is3r0l Overview:描述了插件的基本信息。ITPUB个人空间X/~Mi E3SPF s3\ G
2i z.}3m'e']Y0l Dependencies:描述了插件的依赖关系。ITPUB个人空间 MGu8mD5B
ITPUB个人空间5FtSd0LW
l Runtime:指明运行时的ClassPath。
Z!R+V-B]/k0
o2o7ue!@[/b b0l Extensions:指明插件实现的扩展点。ITPUB个人空间V7C~i0}
`^nP+h~2n0l Extension Points:指明插件提供的扩展点。ITPUB个人空间D'N
|p|+K\A
ITPUB个人空间0[&X t3Q.w9h,V/e-^H
1. OverView:描述了插件的基本信息
{#}r,e+fuF,B3s0ITPUB个人空间 kYH6N,dl
OverView描述了插件的基本信息,如图8所示。
V0AQ%w)eq"]k"R/^0ITPUB个人空间T!^d!k%n.MW
2ql*NHcI*E+Q4q0图8 OverView页面ITPUB个人空间H${O;N3SN*bF
&_H4vD%a*UJ~
uH0l ID:ID是插件的ID号,在Eclipse中是一个具体标识。
:[J-cU5w]VBvc0ITPUB个人空间#IOj-o,V)~)G(V
l Version:Version指明用户所开发的插件的版本号。ITPUB个人空间'C4V(_ PP9c\yM3P(q
ITPUB个人空间\3M@e3x|A3V
B
l Name:指用户所开发的插件的名称。
u(H&z[`NAorW0
7sINjx.t0l Provider:开发者。ITPUB个人空间V
UZr m
X
l3e8^I$ZZ:D!a0l Class:Class是指插件类,它由Eclipse建立并初始化,后面的章节将会详细介绍。
k)g$UK
Gn7q2g0
9M"M;_ID&h!z,s0l Platform. Filter:指定平台相关的一些信息,一般来说用户不需要设定。
VLA#\&wJ w2h@0ITPUB个人空间?!st3@!I.B$K
提示:ID号在Eclipse中是一个全局的标识。很多初学者常常会对不同的插件命名成相同的ID号,这样会导致插件不能加载。ITPUB个人空间Y't(R^G4e,j6~8J
ITPUB个人空间3i;h.P5p9\bS4ad5W
2. Dependencies:描述了插件的依赖关系
%\%VECQ0ITPUB个人空间C2OE{O$xE
Dependencies页面描述了插件的依赖关系,如图9所示,插件依赖org.eclipse.ui和org.eclipse.core.runtime插件。
!g;_
v`J0ITPUB个人空间#QE$im^3BB
ITPUB个人空间4pJ*?p\"Q
图9 Dependencies页面
!` @+QI:XIpR
?2I0ITPUB个人空间{&B@td&As1d7{
Dependencies是一个比较重要的概念。每一个插件有独立的ClassPath,Dependencies会把依赖的插件的ClassPath加入到当前的ClassPath中。ITPUB个人空间-RC/@^3~y
M!h:{@D#xJ!s0提示:插件可以调用依赖的插件中所有导出的类,但插件不能够有循环依赖,所以在设计插件的结构时一定要设计合理,切记、切记。ITPUB个人空间Z/wm1UPd3j
O9s!Wm&_uu03. Runtime:指明了运行时的ClassPath
&|"Gf;G"HY0ITPUB个人空间i^0v)LorW.d
Runtime:指明了运行时的ClassPath。如图10所示,jdom.jar为此插件运行时依赖的包。ITPUB个人空间9V$`!e'G8f^~K
h)DL&YlZD4|0ITPUB个人空间G*P \!n%S`
图10 Runtime页面ITPUB个人空间wAbRoP8HC
,G b
b'cf~0在Exported packages中也加入了一些要导出的包,如果不导出这些包,其它依赖当前插件的插件就用不了当前插件中对应包下的类。
m+E|,KC1z0ITPUB个人空间H3j,}
l1xY
`@x
Runtime也是一个比较重要的概念,它指明了运行时的环境。Eclipse中插件不会引用到系统的ClassPath,每一个插件都有独立的ClassPath。ITPUB个人空间G,o:g,Y2N'Br O$u
J.i%?
XP7B Tj&}1}0提示:很多人在开发插件时,没有通过Runtime指明ClassPath,而是直接添加Jar包,这样,在编译期间可能不会出错,但是在插件运行时会提示类找不到(ClassNotFoundException),就是这个问题。
XA
r`e\h r0
#CO`(M$?a5tV04. Extensions:指明插件实现的扩展点
!I O `Az8^Ik
V%K0ITPUB个人空间2m[.F
K;z\@
Extensions:指明插件实现的扩展点。例如插件要实现“org.eclipse.ui.actionSets”扩展点,如图11所示。
8DY?H@^Oa a*~:G0
!B.Im0`J.pWt0
ITPUB个人空间;qL(r3m+s S.Cgo
图11 Extensions页面ITPUB个人空间K(d2[w;KFx
-k8R1}'D}DJ]3m0Extensions是用户在开发一个插件中用到的扩展点,也是Eclipse开发的精髓所在。后面章节的主要工作就是围绕扩展点展开的。下面为扩展点在Plugin.xml文件中定义的片段。
5YH,qD0Er0
euH8A"Uv,h0<!-- 实现的扩展点 -->
7TP,QA%Z.So0ITPUB个人空间N |zNOC)]1MGf#\
<extension
ql/c b+s0
B+uVy#wdT0point="org.eclipse.ui.actionSets">ITPUB个人空间K}\${r3s'W*oac
ITPUB个人空间*K+~+Up-Tj[&P9f7u7q;B
<actionSet
%yw1V!J9D1Da4R0ITPUB个人空间G\*gV{$xk
label="Sample Action Set"
m2w0}pb6M[b0
L:S\+r"T_j0visible="true"
1Td@ I%cnv0ITPUB个人空间!G`|@3~CO
id="com.test.helloworld.actionSet">ITPUB个人空间`4v|^z
ITPUB个人空间:i+y9na7g
<menu
)V5y-b ["PY0
t#{[uQAQ7HWl$K0label="Sample &Menu"ITPUB个人空间#R!Wtq9YG2J8f/W
/pj2u8n8NhA0id="sampleMenu">
Q:r-C4ipKl6r0ITPUB个人空间"WNEf.z4E
<separatorITPUB个人空间`yd4dIR(t1^
ITPUB个人空间7]ps:^'~4n2d2bK?
name="sampleGroup">ITPUB个人空间6N:_a{4Q/s
ITPUB个人空间 ut"]5Y9Cd+ZVVb
</separator>ITPUB个人空间,{ S"}
W3H^
ITPUB个人空间Rg4Y
qv._
</menu>ITPUB个人空间nRr+lR,j%{
ITPUB个人空间:?,X6G%eMzhp"I2Ap8C
<action
2\ q"B1z-_$r.yq
O4Ne0
!N0JI2m
V&@ge%Ab0label="&Sample Action"
I2?:D"TD1c0ITPUB个人空间!NfR&_-[r5k
icon="icons/sample.gif"
sG&^/Tp/TU0
z$N%T&S~5Y%L{0<!-- 扩展点的实现类 -->ITPUB个人空间t V^I]3FOa
ITPUB个人空间0L"P8Z.F5k8c)Tc
class="com.test.helloworld.actions.SampleAction"ITPUB个人空间,K-O#FO@BPw @J
3JQno$C~'h0tooltip="Hello, Eclipse world"ITPUB个人空间/n"v;i4uL:Xf{i:r
.|)Vb9Ew']o,Pw0menubarPath="sampleMenu/sampleGroup"
OBGI G#g5Ni0ITPUB个人空间B Typu+R.r
toolbarPath="sampleGroup"
a:e6u
AsT
T0ITPUB个人空间_F%z r1uvf:x*y[
id="com.test.helloworld.actions.SampleAction">
!tj8eD8r{_0
?(SkZ6^9\D0</action>ITPUB个人空间]5WK
Igw D4m'D
ITPUB个人空间qO#ec8u?
</actionSet>
.Rb{^/M9aG7P0ITPUB个人空间_4q1H%Uy:},D
</extension>ITPUB个人空间"mu:g$|(S*{
ITPUB个人空间Gm(xx9R;W8@3p@
5. Extension Points:指明了用户插件提供的扩展点ITPUB个人空间,Wb'|&t2g)go
ITPUB个人空间!@-d2gl#my
Extension Points:指明了用户插件提供的扩展点。如图12所示,此处为UI插件所提供的扩展点。
;{{&^9x.c\x7]&D5t!h0ITPUB个人空间5]BS{;I"V~D)d
~$llw$GZ+E0图12 插件提供扩展点
"fM!J:mK-C_%]0ITPUB个人空间o#SU6]%}
Eclipse的强大功能就是提供插件的扩展机制,用户可以实现他人提供的扩展点,也可以通过“Extension Points”为他人提供扩展点。ITPUB个人空间5@
D e!j(e2H]
F}\JD9T(D0提示:实现扩展点和提供的扩展点是两个不同的概念。实现扩展点是利用其他插件提供的扩展点,实现用户想要完成的功能。提供的扩展点是为其他插件提供扩展所需要的接口。
s4D4ma'P D.~0
导入论坛 引用链接 收藏 分享给好友 推荐到圈子 管理 举报
TAG:


