??? 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擴展點也可以如此炮制。 ???????????