最近用Junit对SpringMVC做单元测试的时候,报Failed to load ApplicationContext错误。网上很多资料都说报这个错误是因为Spring的配置文件没有加载,可是实际上我已经全部加载,最后断点调试才发现是因为没有获取到配置文件中的属性值。这里就涉及到我上一篇获取配置文件中的属性值,有兴趣的同学可以回头看看。
首先,我们来看看,我之前是怎么获取到配置文件的路径的,这里还是以conf.properties为例。
public static String getWebRoot() {
ClassLoader classLoader = Thread.currentThread()
.getContextClassLoader();
URL url = classLoader.getResource("/");
String filepath = url.getPath();
filepath = filepath.substring(0, filepath.lastIndexOf("/"));
filepath = filepath.substring(0, filepath.lastIndexOf("/"));
filepath = filepath.substring(0, filepath.lastIndexOf("/"));
log.info("filepath------" + filepath);
return filepath;
}
不在tomcat环境下启动时,URL url = classLoader.getResource("/");这句代码中获取到的url的值为null。这里我有个疑惑,类在编译成功后就被类装载器加载了的,为什么这里会出现url的值为null的情况,知道的同学还望不吝赐教。于是,我就在网上找到另外一种获取配置文件路径的方法。
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.apache.commons.configuration.AbstractConfiguration;
import com.netflix.config.ConfigurationManager;
public class ConfigUtils {
private static ConfigUtils instance = null;
private static AbstractConfiguration config;
private ConfigUtils() {
}
private static void loadConfig() {
InputStream in = null;
try {
Properties prop = new Properties();
in = IOStream.getResourceStream("conf.properties");
prop.load(in);
config = ConfigurationManager.getConfigInstance();
} catch (IOException e) {
throw new RuntimeException("load config error!", e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (Throwable t) {
}
}
}
public static ConfigUtils instance() {
if (instance == null) {
synchronized (ConfigUtils.class) {
if (instance == null) {
loadConfig();
instance = new ConfigUtils();
}
}
}
return instance;
}
public String getString(String key, String defValue) {
return config.getString(key, defValue);
}
public long getLong(String key) {
return config.getLong(key, 0);
}
public int getInt(String key) {
return config.getInt(key, 0);
}
public int getInt(String key, int defaultValue) {
return config.getInt(key, defaultValue);
}
public boolean getBoolean(String key) {
return config.getBoolean(key, false);
}
public String getString(String key) {
return getString(key, null);
}
}
IOStream类
import java.io.InputStream;
import java.net.URL;
public class IOStream {
private IOStream() {
}
public static InputStream getResourceStream(String name) {
InputStream is = IOStream.class.getResourceAsStream(name);
if (is == null) {
is = IOStream.class.getClassLoader().getResourceAsStream(name);
}
if (is == null) {
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(name);
}
return is;
}
public static URL getResource(String name) {
URL url = Thread.currentThread().getContextClassLoader().getResource(name);
if (url == null) {
url = IOStream.class.getClassLoader().getResource(name);
}
if (url == null) {
url = IOStream.class.getResource(name);
}
return url;
}
}
把代码中涉及到的获取conf.properties中某个属性值的方法修改一下。
private final static String REV_SERVERHOST = ConfigUtils.instance()
.getString("receivemail.serverHost");
于是就这样完美的解决了我的问题,后续有时间补上junit对SpringMVC的单元测试代码。补充一点,这种方式需要引入jar包。
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.7.5</version>
</dependency>