Eclipse RCP与Spring的整合
最近上一个项目想在Eclipse RCP中使用Spring,在网上Google了一下发现这方面的资料比较少,知道Spring自己有个Spring-OSGI的项目,可以在 Spring中配置OSGI服务。可是,我只是想在RCP中引入Spring来管理Java Bean,不想去研究那个东西。于是,看看有没有什么简单的方法来解决这个问题。在陈刚的BlOG中找到了问题的部分答案。
于是,我在RCP项目的activator class中加入了
1
private
ApplicationContext ctx;
2
3
private
void
initializeApplicationContext() {
4
ClassLoader oldLoader
=
Thread.currentThread().getContextClassLoader();
5
try
{
6
Thread.currentThread().setContextClassLoader(getDefault().getClass().getClassLoader());
7
this
.ctx
=
new
FileSystemXmlApplicationContext(ProjectUtil.toFullPath(
"
properties/applicationContext.xml
"
));
8
}
finally
{
9
Thread.currentThread().setContextClassLoader(oldLoader);
10
}
11
}
ProjectUtil.toFullPath()方法在陈刚的BLOG中 有详细的说明,是一个获得项目绝对路径的方法。另外在陈刚的BLOG中提到了,在Eclipse 3.2M6中已经不需要转换ClassLoader。但是,我用的是3.2 release版,还是需要转换ClassLoader才能正常工作啊。觉得这并不像陈刚所说的BUG,Eclipse的每个Plugin都有自己的 ClassLoader,所以需要转换吧。
然后,在start方法中调用initializeApplicationContext方法,并为
ctx提供getter
1
public
void
start(BundleContext context)
throws
Exception {
2
super
.start(context);
3
initializeApplicationContext();
4
}
5
6
public
ApplicationContext getApplicationContext() {
7
return
this
.ctx;
8
}
这样我们在其他地方就可以用 Activator.getDefault().getApplicationContext()得到 ApplicationContext了。
但是,新的问题又来了,如何把RCP中的组件也纳入Spring的管理呢,比如ViewPart。我又Google了一下,在今年的TSE2006上有一场报告就提到了Spring同Eclipse RCP的整合 ,里面提到了利用Eclipse的 IExecutableExtensionFactory和IExecutableExtension接口,确实非常的简单。
通常,我们自己定义的ViewPart是通过扩展点 org.eclipse.ui.views,由Eclipse的Workbench自动创建,像这样:
<
extension
point
="org.eclipse.ui.views"
>
<
view
name
="myView"
class
="org.eclipse.example.rcpspring.MyView"
id
="org.eclipse.example.rcpspring.view"
>
</
view
>
</
extension
>
现在我们通过Spring来管理这个view,并假设为其注入一个businessService Bean,像这样:
<
bean
id
="myView"
class
="org.eclipse.example.rcpspring.MyView"
>
<
property
name
="businessService"
ref
="businessService"
/>
</
bean
>
然后,我们要创建一个Extension Factory来在RCP中注册这个view,代码如下:
1
public
class
MyViewExtensionFactory
implements
IExecutableExtensionFactory,
2
IExecutableExtension {
3
private
ViewPart view;
4
5
public
Object create()
throws
CoreException {
6
return
this
.view;
7
}
8
9
public
void
setInitializationData(IConfigurationElement config,
10
String propertyName, Object data)
throws
CoreException {
11
this
.view
=
(MyView)Activator.getDefault().getApplicationContext().getBean(
"
myView
"
);
12
this
.view.setInitializationData(config, propertyName, data);
13
}
14
}
通过
Activator.getDefault().getApplicationContext()来取出上面建立的ApplicationContext。
最后,我们要用这个
MyViewExtensionFactory来注册扩展点,如下:
<
extension
point
="org.eclipse.ui.views"
>
<
view
name
="myView"
class
="org.eclipse.example.rcpspring.MyViewExtensionFactory"
id
="org.eclipse.example.rcpspring.view"
>
</
view
>
</
extension
>
用
MyViewExtensionFactory 来取代原来的
MyView
。
好,已经大功告成。MyView已经成功的进入了Spring框架的管理。其他的RCP扩展点也可以如此炮制。