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

本文详细解析了Java中通过Class和ClassLoader进行资源加载的区别与方法,包括不同路径下的资源查找策略及实际案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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<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加载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值