mybatis通过Resources读取配置文件(从类路径下加载资源)。Resources通过ClassLoaderWrapper(封装ClassLoader读取文件)进行文件加载。
首先看个mybatis中的例子:
@BeforeClass
public static void setup() throws Exception {
createBlogDataSource();
final String resource = "org/apache/ibatis/builder/MapperConfig.xml";
//通过Resources加载配置文件
final Reader reader = Resources.getResourceAsReader(resource);
sqlMapper = new SqlSessionFactoryBuilder().build(reader);
}
Resources提供的主要方法有:
//返回资源的url
getResourceURL(String resource)
getResourceURL(ClassLoader loader, String resource)
//读取资源作为stream返回
getResourceAsStream(String resource)
getResourceAsStream(ClassLoader loader, String resource)
//读取资源作为Properties返回
getResourceAsProperties(String resource)
getResourceAsProperties(ClassLoader loader, String resource)
//读取资源作为Reader返回
getResourceAsReader(String resource)
getResourceAsReader(ClassLoader loader, String resource)
//读取资源作为File返回
getResourceAsFile(String resource)
getResourceAsFile(ClassLoader loader, String resource)
//从url中读取资源返回stream
getUrlAsStream(String urlString)
//从url中读取资源返回Reader
getUrlAsReader(String urlString)
//从url中读取资源返回Properties
getUrlAsProperties(String urlString)
Resources一般使用的场景:
Resources使用的几种方法:
在Resources中使用ClassLoaderWrapper加载文件,如:
public static URL getResourceURL(ClassLoader loader, String resource) throws IOException {
URL url = classLoaderWrapper.getResourceAsURL(resource, loader);
if (url == null) {
throw new IOException("Could not find resource " + resource);
}
return url;
}
在ClassLoaderWrapper中对应的代码为:
public URL getResourceAsURL(String resource, ClassLoader classLoader) {
return getResourceAsURL(resource, getClassLoaders(classLoader));
}
ClassLoader[] getClassLoaders(ClassLoader classLoader) {
return new ClassLoader[]{
//参数指定的类加载器
classLoader,
// 系统指定的默认加载器
defaultClassLoader,
//当前线程绑定的类加载器
Thread.currentThread().getContextClassLoader(),
// 当前类使用的类加载器
getClass().getClassLoader(),
// System ClassLoader(App ClassLoader)
systemClassLoader};
}
URL getResourceAsURL(String resource, ClassLoader[] classLoader) {
URL url;
//循环ClassLoader,通过指定或者默认的ClassLoader读取文件
for (ClassLoader cl : classLoader) {
if (null != cl) {
// look for the resource as passed in...
url = cl.getResource(resource);
// 如果在resource的路径下没有找到,加“/”再进行查询读取
if (null == url) {
url = cl.getResource("/" + resource);
}
// 如果查询到url,终止循环返回结果
if (null != url) {
return url;
}
}
}
return null;
}
ClassLoaderWrapper提供的主要方法有:
getResourceAsURL(String resource)
getResourceAsURL(String resource, ClassLoader classLoader)
getResourceAsStream(String resource)
getResourceAsStream(String resource, ClassLoader classLoader)
classForName(String name)
classForName(String name, ClassLoader classLoader)
其中getResourceAsURL的源码已粘贴在上面,下面再粘贴下getResourceAsStream和classForName的源码:
InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
//循环ClassLoader 数组
for (ClassLoader cl : classLoader) {
if (null != cl) {
// 根据入参resource,读取该路径下文件
InputStream returnValue = cl.getResourceAsStream(resource);
// 如果没有,加上“/”再尝试读取
if (null == returnValue) {
returnValue = cl.getResourceAsStream("/" + resource);
}
//如果读取到,终止循环,返回结果
if (null != returnValue) {
return returnValue;
}
}
}
return null;
}
Class> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {
for (ClassLoader cl : classLoader) {
if (null != cl) {
try {
Class> c = Class.forName(name, true, cl);
if (null != c) {
return c;
}
} catch (ClassNotFoundException e) {
// we'll ignore this until all classloaders fail to locate the class
}
}
}
throw new ClassNotFoundException("Cannot find class: " + name);
}