mybatis源码学习小结-class.getResource方法与claasloader.getResource方法的区别
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文件则。
可以看出,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加载
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加载