ClassLoaderWrapper 类是对 ClassLoader 的包装. 怎么理解了?看下这个方法就知道了.
ClassLoader[] getClassLoaders(ClassLoader classLoader) {
return new ClassLoader[]{
classLoader,
defaultClassLoader,
Thread.currentThread().getContextClassLoader(),
getClass().getClassLoader(),
systemClassLoader};
}
实例化一个 Class.
Class<?> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {
for (ClassLoader cl : classLoader) {
if (null != cl) {
try {
Class<?> c = Class.forName(name, true, cl);
if (null != c) {
return c;
}
} catch (ClassNotFoundException e) {
// we'll ignore this until all classloaders fail to locate the class
}
}
}
throw new ClassNotFoundException("Cannot find class: " + name);
}
查找资源.
URL getResourceAsURL(String resource, ClassLoader[] classLoader) {
URL url;
for (ClassLoader cl : classLoader) {
if (null != cl) {
// look for the resource as passed in...
url = cl.getResource(resource);
// ...but some class loaders want this leading "/", so we'll add it
// and try again if we didn't find the resource
if (null == url) {
url = cl.getResource("/" + resource);
}
// "It's always in the last place I look for it!"
// ... because only an idiot would keep looking for it after finding it, so stop looking already.
if (null != url) {
return url;
}
}
}
// didn't find it anywhere.
return null;
}
Resources 是 Mybatis 提供的用于读取资源文件的工具类,我们可以看到它仅仅是对 ClassLoaderWrapper 一层浅浅的封装.
VFS 是虚拟文件系统通用的 API.
VFS 提供了新增用户自定义 VFS 的功能.
看了下 VFS 的实现类,没发现啥重要的东西.
接下来的这个类比较重要. ResolverUtil.
一个测试接口,比如用于判断一个类是否是另一个类的父类,看某个类上是否存在某个注解等.
/**
* A simple interface that specifies how to test classes to determine if they
* are to be included in the results produced by the ResolverUtil.
*/
public interface Test {
/**
* Will be called repeatedly with candidate classes. Must return True if a class
* is to be included in the results, false otherwise.
*/
boolean matches(Class<?> type);
}
判断 parent 是否是 type 的父类.
public static class IsA implements Test {
private Class<?> parent;
/** Constructs an IsA test using the supplied Class as the parent class/interface. */
public IsA(Class<?> parentType) {
this.parent = parentType;
}
/** Returns true if type is assignable to the parent type supplied in the constructor. */
@Override
public boolean matches(Class<?> type) {
return type != null && parent.isAssignableFrom(type);
}
@Override
public String toString() {
return "is assignable to " + parent.getSimpleName();
}
}
判断 type 上是否存在注解 annotation.
public static class AnnotatedWith implements Test {
private Class<? extends Annotation> annotation;
/** Constructs an AnnotatedWith test for the specified annotation type. */
public AnnotatedWith(Class<? extends Annotation> annotation) {
this.annotation = annotation;
}
/** Returns true if the type is annotated with the class provided to the constructor. */
@Override
public boolean matches(Class<?> type) {
return type != null && type.isAnnotationPresent(annotation);
}
@Override
public String toString() {
return "annotated with @" + annotation.getSimpleName();
}
}
在 packageNames 下查找 parent 的实现类. 将查找到的结果放入 matches 集合.
public ResolverUtil<T> findImplementations(Class<?> parent, String... packageNames) {
if (packageNames == null) {
return this;
}
Test test = new IsA(parent);
for (String pkg : packageNames) {
find(test, pkg);
}
return this;
}
在 packageNames 下查找被注解 annotation 修饰的类. 将查找到的结果放入 matches 集合.
public ResolverUtil<T> findAnnotated(Class<? extends Annotation> annotation, String... packageNames) {
if (packageNames == null) {
return this;
}
Test test = new AnnotatedWith(annotation);
for (String pkg : packageNames) {
find(test, pkg);
}
return this;
}
递归查找.
public ResolverUtil<T> find(Test test, String packageName) {
String path = getPackagePath(packageName);
try {
// 这里用到了 VFS,我们还是看下 VFS 的实现吧.
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;
}
再看下 VFS.
VFS 中定义了两个抽象方法,用于子类实现.
// 从 URL 中搜索和 forPath 匹配的路径.
protected abstract List<String> list(URL url, String forPath) throws IOException;
// 判断此 VFS 是否有效.
public abstract boolean isValid();
VFS 类定义好了获取 VFS 实例的逻辑. 优先使用用户自定义的 VFS,其次是系统实现的.
static VFS createVFS() {
// Try the user implementations first, then the built-ins
List<Class<? extends VFS>> impls = new ArrayList<>();
impls.addAll(USER_IMPLEMENTATIONS);
impls.addAll(Arrays.asList((Class<? extends VFS>[]) IMPLEMENTATIONS));
// Try each implementation class until a valid one is found
VFS vfs = null;
for (int i = 0; vfs == null || !vfs.isValid(); i++) {
Class<? extends VFS> impl = impls.get(i);
try {
vfs = impl.getDeclaredConstructor().newInstance();
if (!vfs.isValid()) {
if (log.isDebugEnabled()) {
log.debug("VFS implementation " + impl.getName() +
" is not valid in this environment.");
}
}
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
log.error("Failed to instantiate " + impl, e);
return null;
}
}
if (log.isDebugEnabled()) {
log.debug("Using VFS adapter " + vfs.getClass().getName());
}
return vfs;
}
关于 DefaultVFS 是读取 Jar 文件. 详细的就不分析了.
分享到:
相关推荐
现在,需要仔细分析Mybatis的执行流程 执行流程 其实,从我们前面的工具类大致可以看出一下步骤 Resources ——》InputStream(解析xml)——》SqlSessionFactoryBuilder().build(inputStream)——》...
源码分析 先看测试类: package uestc.zhangkx; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache....
集合源码分析 Java 笔记 Java 语言相关的API,第三方库和计算机基础理论等知识的学习和整理 更多 : | | 目录 资源 详细目录 Java语言和JDK源码 Java语言的基础理论知识 并发编程 Java并发编程相关的内容,并发包源码...
集合源码分析 java-demos other collect github project leetcode springCloud [Spring Cloud 从入门到实战] () [全网最详细的一篇SpringCloud总结] () [feign] () [Spring Security 真正的前后分离实现] () [Spring...
- 统一下单(统一下单接口、统一扫码)、订单管理、数据分析、财务报表、商户管理、渠道管理、对账系统、系统监控。 ![统一扫码支付](project-bootstrap/zheng-pay.png) > zheng-ucenter 通用用户管理系统, 实现...
│ │ 13.RPC底层通讯原理之Netty线程模型源码分析.wmv │ │ │ ├─14.分库分表之后分布式下如何保证ID全局唯一性 │ │ 14.分库分表之后分布式下如何保证ID全局唯一性.mp4 │ │ │ └─15.大型公司面试必答之...
- [X] [2.6.1 导入 MyBatis 的 jar 包](#导入-MyBatis-的-jar-包) - [X] [2.6.2 配置 MyBatis](#配置-MyBatis) - [X] [2.7 配置 log4j](#配置-log4j) - [X] [2.8 集成基于 Bootstrap 前端框架的 ACE 管理...
java版飞机大战源码 目录(善用Ctrl+F) 注 : 没链接的是还没写 :hot_beverage: 各类知识点总结 下面的文章都有对应的原创精美PDF,在持续更新中,可以来找我催更~ Hibernate AJAX Redis ...... :hot_beverage:Java...
积分管理系统java源码 基础知识 java基础 基本类型(占用的内存)和包装类型 数组和对象 程序控制语句,if、switch...分析Mybatis动态代理的真正实现 手动实现Mini版本的Mybatis 分布式 分布式原理 分布式架构的演进过
面试题包括:基础、并发锁、JVM、设计模式、数据结构、反射/IO、面经、Spring、Spring Boot、数据库、Redis、消息队列、分布式、Zookeeper、Dubbo、Spring Cloud、Mybatis、Maven、大厂真实面经、源码分析
1.需求分析 用户的登录注册 用户信息的更改 用户文件上传 用户文件搜索 用户下载,删除,收藏文件 2.环境准备 JDK 1.8.0_181 tomcat 8.5 spring 4.2.4 RELEASE springmvc 4.2.4 RELEASE mybatis 3.2.8 bootstrap ...
spring、spring组件源码分析 database 数据库 动态的切换数据源,你会怎么切?读写分离? struts 数据结构 thread 多线程、并发 有关多线程的一些小例子,在《Java编程思想》中可以找到源代码 io io操作 socket 网络...
除了项目构建,Maven最核心的功能是软件包的依赖管理,能够自动分析项目所需要的依赖软件包,并到Maven中心仓库去下载。 A)管理依赖的jar包 B)管理工程之间的依赖关系。 3.2. Maven本地仓库 在当前系统用户的...
java技术栈,包括 java基础,jvm,java集合,java并发,IO, 设计模式,http,网络,操作系统,mysql,redis,spring,mybatis,数据结构,算法等。持续更新中,欢迎star! 各领域数据集,工具源码,适合毕业设计、...
基于Springboot+Vue的房价可视化监测系统源码+项目说明.zip 【资源说明】 1、该资源内项目代码都是经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、...
主要技术包括:java基础语法、java⾯向对象(类、对象、封装、继承、多态、 抽象类、接⼝、常见类、内部类、常见修饰符等) 、异常、集合、⽂件、IO、 MYSQL(基本SQL语句操作、多表查询、⼦查询、存储过程、事务、...