`

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<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加载








分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics