mybatis源码学习总结-class.getResource方法与claasloader.getResource方法的区别

Class.getResources(String path) path如果是以 / 开头,就从classpath中去找(classpath可以认为是eclipse的bin目录或者是target的classes目录),
如果不以/开头,就以当前类的位置开始找,也就是它有两种搜索方式。

.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> resolverUtil = new ResolverUtil>();
resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
Set>> 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 find(Test test, String packageName) {
String path = getPackagePath(packageName); //获取package对应的path,将.替换为/

try {
List 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 list(String path) throws IOException {
List names = new ArrayList();
for (URL url : getResources(path)) {
names.addAll(list(url, path));
}
return names;
}


protected static List getResources(String path) throws IOException {
return Collections.list(Thread.currentThread().getContextClassLoader().getResources(path));//


根据上述代码可以看出,外部传入一个包名,
1.首先将包名中的.替换为/
2.使用classloader.getResource获取当前包路径下的所有class资源。
3. 使用classloader加载

你可能感兴趣的:(JAVA基础,开源框架,java,开发工具)