解決了RCP打包時Spring配置的問題

轉載 在Eclipse RCP中使用Spring或者Hibernate收藏
http://blog.csdn.net/ttodle/archive/2006/04/27/679422.aspx


新一篇: JAVA實現用系統關聯的程序打開文件 | 舊一篇: 在 Ubuntu 5.10 上安裝 Sun Java SDK 1.5
在RCP中使用Spring,最關鍵的一點在於spring配置文件的讀取,因爲RCP使用自己的ClassLoader,所以用通常的方法是無法裝載Spring的配置文件。解決的思路是:在讀取Spring配置文件時將RCP的ClassLoader暫時換一下。

在這裏我根據Spring配置文件在項目中的存放位置,給出兩種辦法。

一、配置文件存放在源代碼根目錄下。

假設我有一個叫admin_console的項目,我把Spring的配置文件myspring.xml放在源代碼根據目錄src下,如下圖所示
admin_console
--src
--cn //包名
--com
--chengang
---...... //源代碼類
--myspring.xml //Spring配置文件,位於src目錄下和cn目錄平級
--bin
--lib
--icons
--properties


那麼我們在RCP程序中可以這樣來裝載myspring.xml
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
ctx = new ClassPathXmlApplicationContext("/myspring.xml");
} finally {
Thread.currentThread().setContextClassLoader(oldLoader);
}


二、配置文件存放在項目根目錄的某個子目錄下

項目根目錄和源代碼根目錄是不同的兩個概念。如上圖的項目結構中,src是源代碼根目錄,admin_console是項目根目錄,那麼properties就是項目根目錄下的一個子目錄。

如果將myspring.xml放入到properties目錄中,以上的讀取代碼就沒用了,讀取方法如下:

ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
   ctx = new FileSystemXmlApplicationContext(ProjectUtil.toFullPath("properties/myspring.xml"));
} finally {
Thread.currentThread().setContextClassLoader(oldLoader);
}

其中ProjectUtil.toFullPath是我自己寫的一個方法,主要是得到myspring.xml的絕對路徑,其代碼如下:

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import com.wxxr.management.admin.console.AdminConsolePlugin;

/**
* 用於插件項目和非插件項目,提供兩者通用的方法接口
* @author chengang 2006-3-30
*/
public class ProjectUtil {

private static AbstractUIPlugin plugin = AdminConsolePlugin.getDefault();

private ProjectUtil() {}

/**
* 判斷當前的運行狀態是否爲插件方式
* @return true=插件方式運行
*/
private static boolean isPlugin() {
return plugin != null;
}

public static URL getURL(String path) {
if (isPlugin())//如果是插件
return FileLocator.find(plugin.getBundle(), new Path(path), null);
else
try {
return new URL("file:" + path);
} catch (MalformedURLException e) {
throw new RuntimeException(path + " is error", e);
}
}

public static InputStream getInputStream(String path) {
URL url = getURL(path);
try {
return url.openStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static String toFullPath(String path) {
if (isPlugin()) {
try {
return FileLocator.toFileURL(ProjectUtil.getURL(path)).getPath();
} catch (IOException e) {
throw new RuntimeException(path + " toFullPath is fault", e);
}
} else {
return path;
}
}

}


三、總結

上面兩種方式那一種更好呢?應該是第二種。一般來說,源代碼的編譯文件會打成一個jar包(其實不打成一個JAR包也可以的,我在很多以前就嘗試過將class文件鬆散的部署,如果哪個類要修改,修改後就只部署覆蓋這個 class,看起來也挺方便。不過這種方式不是最佳實踐,不推薦正式發佈時使用,一不心可能引起依賴它的其他類出現問題。)。如果用第一種方式在項目打包後,myspring.xml會打包到jar文件中,這樣不利於今後對myspring進行動態修改。如果用第二種就沒有這種缺點。

很多時候,在Eclipse開發環境中,運行RCP程序沒有問題。但導出項目後,在獨立的環境中卻報配置文件(不光是Spring)找不到的錯誤,解決的方法都基本與此相同。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章