版本 org.reflections reflections 0.9.12
使用Reflections可以很轻松的获取以下元数据信息:
获取某个类型的所有子类;比如,有一个父类是Interface,可以获取到Interface的所有子类。
Reflections reflections = 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:
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.addScanners(((Scanner) ((Class) param).newInstance())); } catch (Exception e) { /*fallback*/ }
}
builder.addUrls(ClasspathHelper.forClass((Class) param, classLoaders));
filter.includePackage(((Class) param));
}
else if (param instanceof Scanner) { scanners.add((Scanner) param); }
else if (param instanceof URL) { builder.addUrls((URL) param); }
else if (param instanceof ClassLoader) { /* already taken care */ }
else if (param instanceof Predicate) { filter.add((Predicate<String>) param); }
else if (param instanceof ExecutorService) { builder.setExecutorService((ExecutorService) param); }
else if (Reflections.log != null) { throw new ReflectionsException("could not use param " + param); }
}
1.4.当 FilterBuilder 中没有任何一个url时,从类加载器中获取URL
1.4.1. 判断是否存在有效类加载器,
ClassLoader contextClassLoader = contextClassLoader(), staticClassLoader = staticClassLoader();
return contextClassLoader != null ?
staticClassLoader != null && contextClassLoader != staticClassLoader ?
new ClassLoader[]{contextClassLoader, staticClassLoader} :
new ClassLoader[]{contextClassLoader} :
new ClassLoader[] {};
public static ClassLoader contextClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
public static ClassLoader staticClassLoader() {
return Reflections.class.getClassLoader();
}
1.4.2. 判断类加载器类型,如果是 URLClassLoader 则从中获取URL,如果不是则寻找父类加载器(双子委派模型)是否是URLClassLoader,如果是则从中获取URL
for (ClassLoader classLoader : loaders) {
while (classLoader != null) {
if (classLoader instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) classLoader).getURLs();
if (urls != null) {
result.addAll(Arrays.asList(urls));
}
}
classLoader = classLoader.getParent();
}
}
1.5.将过滤器,类加载器,scanners等添加到 ConfigurationBuilder 环境创造器中
builder.filterInputsBy(filter);
if (!scanners.isEmpty()) {
builder.setScanners(scanners.toArray(new Scanner[scanners.size()]));
}
if (!loaders.isEmpty()) {
builder.addClassLoaders(loaders);
}
public ConfigurationBuilder filterInputsBy(Predicate<String> inputsFilter) {
this.inputsFilter = inputsFilter;
return this;
}
1.6.然后将ConfigurationBuilder(实现了Configuration) 传入Reflections的构造方法中
public Reflections(final Object... params) {
this(ConfigurationBuilder.build(params));
}
public Reflections(final Configuration configuration) {
...
}
1.7.将Store store 清空
store = new Store();
1.8.如果 configuration 中scanners不为空,遍历scanners将configuration 放到每一个scanner中
for (Scanner scanner : configuration.getScanners()) {
scanner.setConfiguration(configuration);
}
1.9.执行scan()方法进行扫描
//线程池可以在new Reflections(pageName)时,通过入参传递
//或者采用如下方式
public ConfigurationBuilder setExecutorService(ExecutorService executorService) {
this.executorService = executorService;
return this;
}
1.10.protected void scan(URL url)
String path = file.getRelativePath();
String fqn = path.replace('/', '.');
for (final Vfs.File file : dir.getFiles()){...}
Predicate<String> inputsFilter = configuration.getInputsFilter();
f (inputsFilter == null || inputsFilter.test(path) || inputsFilter.test(fqn)){...}
//校验方式为正则校验
public boolean test(final String regex) {return pattern.matcher(regex).matches();}
if (scanner.acceptsInput(path) || scanner.acceptsInput(fqn)) {
classObject = scanner.scan(file, classObject, store);
}
public boolean acceptsInput(String file) {
return file.endsWith(".class");
}
public boolean acceptsInput(String file) {
return !file.endsWith(".class"); //not a class
}
从文件流中获取class文件 ClassFile
然后进行校验Scanner 的校验
String className = getMetadataAdapter().getClassName(cls);
String superclass = getMetadataAdapter().getSuperclassName(cls);
if (acceptResult(superclass)) {
//添加到store中
put(store, superclass, className);
}
//获取接口,将接口和父类都放入store中
for (String anInterface : (List<String>) getMetadataAdapter().getInterfacesNames(cls)) {
if (acceptResult(anInterface)) {
put(store, anInterface, className);
}
}
//put方法如下
protected void put(Store store, String key, String value) {
store.put(Utils.index(getClass()), key, value);
}
判断是否需要展开父类,默认为true,
从store中获取key为SubTypesScanner的map中的数据,获取接口的类和实现类信息,向上寻找其未扫描的父类,最后添加到store的key为SubTypesScanner的map中
String index = index(SubTypesScanner.class);
Set<String> keys = store.keys(index);
keys.removeAll(store.values(index));
for (String key : keys) {
final Class<?> type = forName(key, loaders());
if (type != null) {
expandSupertypes(store, key, type);
}
}
private void expandSupertypes(Store store, String key, Class<?> type) {
for (Class<?> supertype : ReflectionUtils.getSuperTypes(type)) {
if (store.put(SubTypesScanner.class, supertype.getName(), key)) {
if (log != null) log.debug("expanded subtype {} -> {}", supertype.getName(), key);
expandSupertypes(store, supertype.getName(), supertype);
}
}
ReflectionUtils.getSuperTypes(type) //方法查询到了父类
创建出一个Reflections含有store,filter,sacnners的Reflections
/**
* targetInterface 需要查询子类的接口,
*/
Set<Class<?>> implClazz = reflections.getSubTypesOf((Class<Object>) targetInterface);
2.1.从store中获取目标接口的子类
store.getAll(SubTypesScanner.class, type.getName())
2.2.通过类加载器加载当前子类,当前类加载器为null,通过上述1.4.1的方法获取默认加载器
public static <T> Set<Class<? extends T>> forNames(final Collection<String> classes, ClassLoader... classLoaders) {
return classes.stream()
.map(className -> (Class<? extends T>) forName(className, classLoaders))
.filter(Objects::nonNull)
.collect(Collectors.toCollection(LinkedHashSet::new));
}
2.3 通过类全路径加载类
public static Class<?> forName(String typeName, ClassLoader... classLoaders) {
try { return classLoader.loadClass(type); }
}
2.4 最后获取到了实现类的反射反射对象列表