新增一个类描述注解
import java.lang.annotation.*;
/**
* 类描述注解
*
* @author ruliang
* @date 2020年3月23日
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.FIELD,ElementType.TYPE})
public @interface ClassAnnotation {
//注解成员,default表示默认值
public String value() default "";
//类型 (1表示E入职) 其他系统请自定义数值
public String type();
}
新增Class工具类
import java.io.File;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* Class工具类
*/
public class ClazzUtils {
private static final String CLASS_SUFFIX = ".class";
private static final String CLASS_FILE_PREFIX = File.separator + "classes" + File.separator;
private static final String PACKAGE_SEPARATOR = ".";
/**
* 查找包下的所有类的名字
* @param packageName
* @param showChildPackageFlag 是否需要显示子包内容
* @return List集合,内容为类的全名
*/
public static List<Map> getClazzName(String packageName, boolean showChildPackageFlag,String type) {
List<String> result = new ArrayList<>();
List<Map> list = new ArrayList<>();
String suffixPath = packageName.replaceAll("\\.", "/");
ClassLoader loader = Thread.currentThread().getContextClassLoader();
try {
Enumeration<URL> urls = loader.getResources(suffixPath);
while(urls.hasMoreElements()) {
URL url = urls.nextElement();
if(url != null) {
String protocol = url.getProtocol();
if("file".equals(protocol)) {
String path = url.getPath();
System.out.println(path);
result.addAll(getAllClassNameByFile(new File(path), showChildPackageFlag));
} else if("jar".equals(protocol)) {
JarFile jarFile = null;
try{
jarFile = ((JarURLConnection) url.openConnection()).getJarFile();
} catch(Exception e){
e.printStackTrace();
}
if(jarFile != null) {
result.addAll(getAllClassNameByJar(jarFile, packageName, showChildPackageFlag));
}
}
}
}
for (String string : result) {
Class<?> clazz = Class.forName(string);
ClassAnnotation classAnnotation = clazz.getDeclaredAnnotation(ClassAnnotation.class);
Map<String,String> map = new HashMap<>();
map.put("class",string);
if (classAnnotation != null && classAnnotation.type().equals(type)) {
map.put("description",classAnnotation.value());
list.add(map);
}
}
} catch (Exception e) {
e.printStackTrace();
}
loader.clearAssertionStatus();
return list;
}
/**
* 递归获取所有class文件的名字
* @param file
* @param flag 是否需要迭代遍历
* @return List
*/
private static List<String> getAllClassNameByFile(File file, boolean flag) {
List<String> result = new ArrayList<>();
if(!file.exists()) {
return result;
}
if(file.isFile()) {
String path = file.getPath();
// 注意:这里替换文件分割符要用replace。因为replaceAll里面的参数是正则表达式,而windows环境中File.separator="\\"的,因此会有问题
if(path.endsWith(CLASS_SUFFIX)) {
path = path.replace(CLASS_SUFFIX, "");
// 从"/classes/"后面开始截取
String clazzName = path.substring(path.indexOf(CLASS_FILE_PREFIX) + CLASS_FILE_PREFIX.length())
.replace(File.separator, PACKAGE_SEPARATOR);
if(-1 == clazzName.indexOf("$")) {
result.add(clazzName);
}
}
return result;
} else {
File[] listFiles = file.listFiles();
if(listFiles != null && listFiles.length > 0) {
for (File f : listFiles) {
if(flag) {
result.addAll(getAllClassNameByFile(f, flag));
} else {
if(f.isFile()){
String path = f.getPath();
if(path.endsWith(CLASS_SUFFIX)) {
path = path.replace(CLASS_SUFFIX, "");
// 从"/classes/"后面开始截取
String clazzName = path.substring(path.indexOf(CLASS_FILE_PREFIX) + CLASS_FILE_PREFIX.length())
.replace(File.separator, PACKAGE_SEPARATOR);
if(-1 == clazzName.indexOf("$")) {
result.add(clazzName);
}
}
}
}
}
}
return result;
}
}
/**
* 递归获取jar所有class文件的名字
* @param jarFile
* @param packageName 包名
* @param flag 是否需要迭代遍历
* @return List
*/
private static List<String> getAllClassNameByJar(JarFile jarFile, String packageName, boolean flag) {
List<String> result = new ArrayList<>();
Enumeration<JarEntry> entries = jarFile.entries();
while(entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
String name = jarEntry.getName();
// 判断是不是class文件
if(name.endsWith(CLASS_SUFFIX)) {
name = name.replace(CLASS_SUFFIX, "").replace("/", ".");
if(flag) {
// 如果要子包的文件,那么就只要开头相同且不是内部类就ok
if(name.startsWith(packageName) && -1 == name.indexOf("$")) {
result.add(name);
}
} else {
// 如果不要子包的文件,那么就必须保证最后一个"."之前的字符串和包名一样且不是内部类
if(packageName.equals(name.substring(0, name.lastIndexOf("."))) && -1 == name.indexOf("$")) {
result.add(name);
}
}
}
}
return result;
}
}
在类里面添加自定义注解
/**
* 子流程结束改变主流程监听器(E入职通用)
*/
@ClassAnnotation(value = "子流程结束改变主流程监听器(E入职通用)",type = "1")
public class CurrencyChangeParentListene{
}
/**
* 改变任务的执行人(E入职通用)
*/
@ClassAnnotation(value = "改变任务的执行人(E入职通用)",type = "1")
public class CurrencyChangeProcessAssigneeListener {
}
/**
* 主流程发起子流程监听器(E入职通用)
*/
@ClassAnnotation(value = "主流程发起子流程监听器(E入职通用)",type = "1")
public class CurrencyStartSubprocessListener{
}
测试
/**
* 监听器控制器
*/
@RestController
@RequestMapping("/listener")
@Api(value = "监听器控制器", tags = "监听器接口")
public class ListenerController {
@ApiOperation(value = "获取监听器")
@PostMapping(value = "/getListenerList")
@LoginExclude
public Result getListenerList(@RequestBody ListenerParam listenerParam) {
return Result.ok(ClazzUtils.getClazzName(listenerParam.getPackageName(), false,listenerParam.getType()));
}
}
?
|