??? Eclipse RCP與Spring的整合
???
最近上一個(gè)項(xiàng)目想在Eclipse RCP中使用Spring,在網(wǎng)上Google了一下發(fā)現(xiàn)這方面的資料比較少,知道Spring自己有個(gè)Spring-OSGI的項(xiàng)目,可以在Spring中配置OSGI服務(wù)。可是,我只是想在RCP中引入Spring來(lái)管理Java Bean,不想去研究那個(gè)東西。于是,看看有沒有什么簡(jiǎn)單的方法來(lái)解決這個(gè)問(wèn)題。在陳剛的BlOG中找到了問(wèn)題的部分答案。
??????
??????? 于是,我在RCP項(xiàng)目的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中有詳細(xì)的說(shuō)明,是一個(gè)獲得項(xiàng)目絕對(duì)路徑的方法。另外在陳剛的BLOG中提到了,在Eclipse 3.2M6中已經(jīng)不需要轉(zhuǎn)換ClassLoader。但是,我用的是3.2 release版,還是需要轉(zhuǎn)換ClassLoader才能正常工作啊。覺得這并不像陳剛所說(shuō)的BUG,Eclipse的每個(gè)Plugin都有自己的ClassLoader,所以需要轉(zhuǎn)換吧。
??? 然后,在start方法中調(diào)用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?????}
這樣我們?cè)谄渌胤骄涂梢杂?/span>Activator.getDefault().getApplicationContext()得到ApplicationContext了。
??????? 但是,新的問(wèn)題又來(lái)了,如何把RCP中的組件也納入Spring的管理呢,比如ViewPart。我又Google了一下,在今年的TSE2006上有一場(chǎng)報(bào)告就提到了Spring同Eclipse RCP的整合 ,里面提到了利用Eclipse的? ?? IExecutableExtensionFactory和IExecutableExtension接口,確實(shí)非常的簡(jiǎn)單。
? ? ? ? 通常,我們自己定義的ViewPart是通過(guò)擴(kuò)展點(diǎn)org.eclipse.ui.views,由Eclipse的Workbench自動(dòng)創(chuàng)建,像這樣:
<extension?point="org.eclipse.ui.views">
<view
????????? name="myView"
????????? class="org.eclipse.example.rcpspring.MyView"
????????? id="org.eclipse.example.rcpspring.view">
</view>
</extension>
?????
?????? 現(xiàn)在我們通過(guò)Spring來(lái)管理這個(gè)view,并假設(shè)為其注入一個(gè)businessService Bean,像這樣:
<bean?id="myView" class="org.eclipse.example.rcpspring.MyView">
<property?name="businessService" ref="businessService"/>
</bean>
?????? 然后,我們要?jiǎng)?chuàng)建一個(gè)Extension Factory來(lái)在RCP中注冊(cè)這個(gè)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?}
通過(guò)Activator.getDefault().getApplicationContext()來(lái)取出上面建立的ApplicationContext。
????? 最后,我們要用這個(gè)MyViewExtensionFactory來(lái)注冊(cè)擴(kuò)展點(diǎn),如下:
<extension?point="org.eclipse.ui.views">
<view
name="myView"
class="org.eclipse.example.rcpspring.MyViewExtensionFactory"
id="org.eclipse.example.rcpspring.view">
</view>
</extension>
用MyViewExtensionFactory 來(lái)取代原來(lái)的MyView 。
? ? ?? 好,已經(jīng)大功告成。MyView已經(jīng)成功的進(jìn)入了Spring框架的管理。其他的RCP擴(kuò)展點(diǎn)也可以如此炮制。 ???????????