标签:media extra cto 没有 bsp url findjar on() UNC
本文,我们来分享 MyBatis 的 IO 模块,对应 io 包。如下图所示:
在 《精尽 MyBatis 源码解析 —— 项目结构一览》 中,简单介绍了这个模块如下:
资源加载模块,主要是对类加载器进行封装,确定类加载器的使用顺序,并提供了加载类文件以及其他资源文件的功能 。
本文涉及的类如下图所示:
org.apache.ibatis.io.ClassLoaderWrapper ,ClassLoader 包装器。可使用多个 ClassLoader 加载对应的资源,直到有一成功后返回资源。
| // ClassLoaderWrapper.java | 
defaultClassLoader 属性,默认 ClassLoader 对象。目前不存在初始化该属性的构造方法。可通过 ClassLoaderWrapper.defaultClassLoader = xxx 的方式,进行设置。systemClassLoader 属性,系统 ClassLoader 对象。在构造方法中,已经初始化。#getClassLoaders(ClassLoader classLoader) 方法,获得 ClassLoader 数组。代码如下:
| // ClassLoaderWrapper.java | 
#getResourceAsURL(String resource, ...) 方法,获得指定资源的 URL 。代码如下:
| // ClassLoaderWrapper.java | 
#getClassLoaders(ClassLoader classLoader) 方法,获得 ClassLoader 数组。再调用 #getResourceAsURL(String resource, ClassLoader[] classLoader) 方法,获得指定资源的 InputStream 。代码如下:
| // ClassLoaderWrapper.java | 
#getResourceAsStream(String resource, ...) 方法,获得指定资源的 InputStream 对象。代码如下:
| // ClassLoaderWrapper.java | 
#getClassLoaders(ClassLoader classLoader) 方法,获得 ClassLoader 数组。再调用 #getResourceAsStream(String resource, ClassLoader[] classLoader) 方法,获得指定资源的 InputStream 。代码如下:
| // ClassLoaderWrapper.java | 
#classForName(String name, ...) 方法,获得指定类名对应的类。代码如下:
| // ClassLoaderWrapper.java | 
#getClassLoaders(ClassLoader classLoader) 方法,获得 ClassLoader 数组。再调用 #classForName(String name, ClassLoader[] classLoader) 方法,获得指定类名对应的类。代码如下:
| // ClassLoaderWrapper.java | 
org.apache.ibatis.io.Resources ,Resource 工具类。
| // Resources.java | 
基于 classLoaderWrapper 属性的封装。
#getResourceURL(String resource) 静态方法,获得指定资源的 URL 。代码如下:
| // Resources.java | 
#getResourceAsStream(String resource) 静态方法,获得指定资源的 InputStream 。代码如下:
| // Resources.java | 
#getResourceAsReader(String resource) 静态方法,获得指定资源的 Reader 。代码如下:
| // Resources.java | 
#getResourceAsFile(String resource) 静态方法,获得指定资源的 File 。代码如下:
| // Resources.java | 
classLoaderWrapper 属性的封装。#getResourceAsProperties(ClassLoader loader) 静态方法,获得指定资源的 Properties 。代码如下:
| // Resources.java | 
#getUrlAsStream(String urlString) 静态方法,获得指定 URL 。代码如下:
| // Resources.java | 
#getUrlAsReader(String urlString) 静态方法,指定 URL 的 Reader 。代码如下:
| // Resources.java | 
#getUrlAsReader(String urlString) 静态方法,指定 URL 的 Properties 。代码如下:
| // Resources.java | 
#classForName(String className) 静态方法,获得指定类名对应的类。代码如下:
| // Resources.java | 
org.apache.ibatis.io.ResolverUtil ,解析器工具类,用于获得指定目录符合条件的类们。
Test ,匹配判断接口。代码如下:
| // ResolverUtil.java 内部类 | 
IsA ,实现 Test 接口,判断是否为指定类。代码如下:
| // ResolverUtil.java 内部类 | 
AnnotatedWith ,判断是否有指定注解。代码如下:
| // ResolverUtil.java 内部类 | 
| // ResolverUtil.java | 
#find(Test test, String packageName) 方法,获得指定包下,符合条件的类。代码如下:
| // ResolverUtil.java | 
<1> 处,调用 #getPackagePath(String packageName) 方法,获得包的路径。代码如下:
| // ResolverUtil.java | 
<2> 处,获得路径下的所有文件。详细解析,见 「5. VFS」 。<3> 处,遍历 Java Class 文件,调用 #addIfMatching(Test test, String fqn) 方法,如果匹配,则添加到结果集。代码如下:
| // ResolverUtil.java | 
* 使用对应的 `test` 的进行匹配。
#findImplementations(Class<?> parent, String... packageNames) 方法,判断指定目录下们,符合指定类的类们。代码如下:
| // ResolverUtil.java | 
#findAnnotated(Class<? extends Annotation> annotation, String... packageNames) 方法,判断指定目录下们,符合指定注解的类们。代码如下:
| // ResolverUtil.java | 
org.apache.ibatis.io.VFS ,虚拟文件系统( Virtual File System )抽象类,用来查找指定路径下的的文件们。
| // VFS.java | 
IMPLEMENTATIONS 静态属性,内置的 VFS 实现类的数组。目前 VFS 有 JBoss6VFS 和 DefaultVFS 两个实现类。USER_IMPLEMENTATIONS 静态属性,自定义的 VFS 实现类的数组。可通过 #addImplClass(Class<? extends VFS> clazz) 方法,进行添加。#getInstance() 方法,获得 VFS 单例。代码如下:
| // VFS.java | 
INSTANCE 属性,最后通过 #createVFS() 静态方法来创建,虽然 USER_IMPLEMENTATIONS 和 IMPLEMENTATIONS 有多种 VFS 的实现类,但是最终选择的是,最后一个符合的创建的 VFS 对象。因为 VFS 自己有反射调用方法的需求,所以自己实现了三个方法。代码如下:
| // VFS.java | 
#isValid() 抽象方法,判断是否为合法的 VFS 。代码如下:
| // VFS.java | 
#list(String path) 方法,获得指定路径下的所有资源。代码如下:
| // VFS.java | 
先调用 #getResources(String path) 静态方法,获得指定路径下的 URL 数组。代码如下:
| // VFS.java | 
后遍历 URL 数组,调用 #list(URL url, String forPath) 方法,递归的列出所有的资源们。代码如下:
| // VFS.java | 
org.apache.ibatis.io.DefaultVFS ,继承 VFS 抽象类,默认的 VFS 实现类。
| // DefaultVFS.java | 
true ,因为默认支持。#list(URL url, String path) 方法,递归的列出所有的资源们。代码如下:
| // DefaultVFS.java | 
<1> 和 <2> 处的代码,基本就可以了。大体逻辑就是,不断递归文件夹,获得到所有文件。设计到对 Jar 的处理,感兴趣的胖友,可以自己理解下。?? 艿艿暂时没看的特别细。#findJarForResource(URL url) 方法,如果 url 指向的是 Jar Resource ,则返回该 Jar Resource ,否则返回 null 。代码如下:
| // DefaultVFS.java | 
url 以 .jar 结尾。#isJar(URL url) 方法,判断是否为 JAR URL 。代码如下:
| // DefaultVFS.java | 
#listResources(JarInputStream jar, String path) 方法,遍历 Jar Resource 。代码如下:
| // DefaultVFS.java | 
org.apache.ibatis.io.JBoss6VFS ,继承 VFS 抽象类,基于 JBoss 的 VFS 实现类。使用时,需要引入如下:
| <dependency> | 
因为实际基本没使用到,所以暂时不分析这个类
标签:media extra cto 没有 bsp url findjar on() UNC
原文地址:https://www.cnblogs.com/siye1989/p/11621486.html