org.reflections 接口通过反射获取实现类源码研究
版本 org.reflections reflections 0.9.12
Reflections通过扫描classpath,索引元数据,并且允许在运行时查询这些元数据。
使用Reflections可以很轻松的获取以下元数据信息:
获取某个类型的所有子类;比如,有一个父类是Interface,可以获取到Interface的所有子类。
- 获取某个注解的所有类型/字段变量,支持注解参数匹配。
- 使用正则表达式获取所有匹配的资源文件
- 获取特定签名方法。
- 接口通过反射获取实现类步骤和源码解析
## 第一步: 通过包名称获取 Reflections
Reflections reflections = new Reflections(pageName);
new Reflections(pageName) 详细源码解析:
ConfigurationBuilder.build(params)
1.1.将入参扁平化处理,加入 parameters 列表中
if (params != null) {
for (Object param : params) {
if (param != null) {
if (param.getClass().isArray()) { for (Object p : (Object[]) param) if (p != null) parameters.add(p); }
else if (param instanceof Iterable) { for (Object p : (Iterable) param) if (p != null) parameters.add(p); }
else parameters.add(param);
}
}
}
1.2.判断入参中是否包含类加载器,如果有类加载器就将其加入加载器列表loaders中,如果没有则创建一个空的类加载器数组classLoaders
List<ClassLoader> loaders = new ArrayList<>();
for (Object param : parameters) if (param instanceof ClassLoader) loaders.add((ClassLoader) param);
1.3.遍历扁平化处理后的入参列表 parameters:
- 如果元素为string,Url类型则将该url加入过滤器构造器FilterBuilder中
- 如果是Class信息则将其转换为Url再加入过滤器构造器中
- 如果是Scanner则添加到搜索器列表scanners中
for (Object param : parameters) {
if (param instanceof String) {
builder.addUrls(ClasspathHelper.forPackage((String) param, classLoaders));
filter.includePackage((String) param);
}
else if (param instanceof Class) {
if (Scanner.class.isAssignableFrom((Class) param)) {
try { builder.add