Class.getResources(String path) path如果是以 / 开头,就从classpath中去找(classpath可以认为是eclipse的bin目录或者是target的classes目录),
如果不以/开头,就以当前类的位置开始找,也就是它有两种搜索方式。
.classloader不能以/为开头,classloader.getResource只能从classpath中去找。
例如在src/com/test/example2目录下存在aa.xml文件则。
可以看出,classloader.getResource在当前路径下找不到相关资源,但是class.getResource方法可以找到相关资源
以上执行结果可以看出,class.getResource和classloader.getResource方法在当前classpath下都看可以找到指定的资源,唯一的区别是class.getResouece以/开头,classloader.getResource不以/开头。
class.getResourceAsStream 和getClassLoader().getResourceAsStream
class.getResourceAsStream,如之前的class.getResource一样,只不过包装了一个流,返回给你一个输入流。
现在来看一段mybstis的源码。
根据上述代码可以看出,外部传入一个包名,
1.首先将包名中的.替换为/
2.使用classloader.getResource获取当前包路径下的所有class资源。
3. 使用classloader加载
如果不以/开头,就以当前类的位置开始找,也就是它有两种搜索方式。
.classloader不能以/为开头,classloader.getResource只能从classpath中去找。
例如在src/com/test/example2目录下存在aa.xml文件则。
@Test
public void test1()
{
System.out.println(TestResource.class.getResource("aa.xml")); --没有以/开头,从当前类位置去找。
System.out.println(TestResource.class.getClassLoader().getResource("aa.xml"));
System.out.println("TestResource.test1()");
}
执行结果为:
file:/C:/Users/ltchyj/workspace/testapp2/bin/com/test/example2/aa.xml
null
TestResource.test1()
可以看出,classloader.getResource在当前路径下找不到相关资源,但是class.getResource方法可以找到相关资源
@Test
public void test2()
{
System.out.println(TestResource.class.getResource("/com/test/example2/aa.xml")); //以/为开头。从classpath下面去找。
System.out.println(TestResource.class.getClassLoader().getResource("com/test/example2/aa.xml"));//classloader不能以/为开头,
System.out.println("TestResource.test2()");
}
执行结果为:
file:/C:/Users/ltchyj/workspace/testapp2/bin/com/test/example2/aa.xml
file:/C:/Users/ltchyj/workspace/testapp2/bin/com/test/example2/aa.xml
TestResource.test2()
以上执行结果可以看出,class.getResource和classloader.getResource方法在当前classpath下都看可以找到指定的资源,唯一的区别是class.getResouece以/开头,classloader.getResource不以/开头。
@Test
public void test3()
{
System.out.println(TestResource.class.getResource("")); //获取的
System.out.println(TestResource.class.getClassLoader().getResource(""));
System.out.println("TestResource.test3()");
}
file:/C:/Users/ltchyj/workspace/testapp2/bin/com/test/example2/
file:/C:/Users/ltchyj/workspace/testapp2/bin/
TestResource.test3()
class.getResourceAsStream 和getClassLoader().getResourceAsStream
class.getResourceAsStream,如之前的class.getResource一样,只不过包装了一个流,返回给你一个输入流。
现在来看一段mybstis的源码。
public void registerAliases(String packageName, Class<?> superType){ //这里传入的是Object.class
ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
Set<Class<? extends Class<?>>> typeSet = resolverUtil.getClasses();
for(Class<?> type : typeSet){
// Ignore inner classes and interfaces (including package-info.java)
// Skip also inner classes. See issue #6
if (!type.isAnonymousClass() && !type.isInterface() && !type.isMemberClass()) {
registerAlias(type);
}
}
public ResolverUtil<T> find(Test test, String packageName) {
String path = getPackagePath(packageName); //获取package对应的path,将.替换为/
try {
List<String> children = VFS.getInstance().list(path);
for (String child : children) {
if (child.endsWith(".class")) {
addIfMatching(test, child);
}
}
} catch (IOException ioe) {
log.error("Could not read package: " + packageName, ioe);
}
return this;
}
protected String getPackagePath(String packageName) {
return packageName == null ? null : packageName.replace('.', '/');
}
public List<String> list(String path) throws IOException {
List<String> names = new ArrayList<String>();
for (URL url : getResources(path)) {
names.addAll(list(url, path));
}
return names;
}
protected static List<URL> getResources(String path) throws IOException {
return Collections.list(Thread.currentThread().getContextClassLoader().getResources(path));//
根据上述代码可以看出,外部传入一个包名,
1.首先将包名中的.替换为/
2.使用classloader.getResource获取当前包路径下的所有class资源。
3. 使用classloader加载