8. jvm-sandbox之服务接口扫描2
服务接口扫描2
一、概述
之前写过一版利用jvm-sandbox扫描服务接口的文章,最近重新看了一下源码中的样例,发现了一个新接口Progress,利用它可以监控到渲染的过程。它可以让服务接口信息的获取变得更加简洁便利。
二、Progress接口代码
/**
* 进度报告
* <p>
* 观察类是需要对类进行增强,有时候需要对大量的类进行渲染,耗时比较长。
* 通过这样的报告方式可以让外部感知到当前渲染的进度。
* 在渲染完成之前,事件是不会触发给到{@link EventListener}的
* </p>
*/
interface Progress {
/**
* 进度开始
*
* @param total 总共需要渲染类的总数
*/
void begin(int total);
/**
* 进度报告(成功)
*
* @param clazz 当前进行行变的类
* @param index 当前形变类的序号,从0开始
*/
void progressOnSuccess(Class<?> clazz, int index);
/**
* 进度报告(失败)
*
* @param clazz 当前进行行变的类
* @param index 当前形变类的序号,从0开始
* @param cause 失败异常
*/
void progressOnFailed(Class<?> clazz, int index, Throwable cause);
/**
* 进度结束
* <p>如果是add方法,则影响的数量是递增;</p>
* <p>如果是remove方法,则影响的数量是递减;</p>
* <p>当彻remove完成之后,cCnt = mCnt = 0;</p>
*
* @param cCnt 影响类总数
* @param mCnt 影响方法总数
*/
void finish(int cCnt, int mCnt);
}
三、获取方法
第一步 实现Progress 接口
import com.alibaba.fastjson.JSONObject;
import com.alibaba.jvm.sandbox.api.resource.ModuleEventWatcher;
import com.custom.util.HttpUtil;
import com.custom.util.InstanceUtils;
import org.slf4j.Logger;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ControllerProcessInfo implements ModuleEventWatcher.Progress {
Logger lifeCLogger;
public String serviceName;
public List<InterfaceInfo> interfaceInfoList;
public ControllerProcessInfo(Logger lifeCLogger,String serviceName) {
this.lifeCLogger = lifeCLogger;
this.interfaceInfoList=new ArrayList<>();
this.serviceName=serviceName;
}
public List<InterfaceInfo> getInterfaceInfoList(){
return this.interfaceInfoList;
}
@Override
public void begin(int total) {
lifeCLogger.debug("渲染总个数:{}", total);
}
@Override
public void progressOnSuccess(Class<?> clazz, int index) {
lifeCLogger.debug("{} 渲染成功:{}", index, clazz.getName());
InterfaceInfo interfaceInfo=new InterfaceInfo();
//**通过反射获取注解的value。这里获取RequestMapping注解的value**
ClassMappingInfo classMappingInfo=new ClassMappingInfo();
classMappingInfo.setClassName(clazz.getName());
String basePath = "";
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.toString().contains("RequestMapping")) {//直接使用getAnnotation(RequestMapping.class)获取不到annotation. annotation.getClass().getName()的值是com.sun.proxy.$Proxy80
String[] s = (String[]) InstanceUtils.doMethodByName("value", annotation);
basePath = s[0];
classMappingInfo.setBasePath(basePath);
}
}
interfaceInfo.setClassInfo(classMappingInfo);
List<MethodMappingInfo> methodMappingInfoList=new ArrayList<>();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
Annotation[] annotations_m = method.getAnnotations();
for (Annotation annotation_m : annotations_m) {
//lifeCLogger.debug("annotation_m:{}", annotation_m.toString());//annotation_m:@org.springframework.web.bind.annotation.RequestMapping(headers=[], path=[], method=[], produces=[], name=, params=[], value=[/insertUser], consumes=[])
if (annotation_m.toString().contains("org.springframework.web.bind.annotation") && annotation_m.toString().contains("Mapping") ) {
//获取注解值
String[] s_m = (String[]) InstanceUtils.doMethodByName("value", annotation_m);
String path = s_m[0];
MethodMappingInfo methodMappingInfo=new MethodMappingInfo();
methodMappingInfo.setMethodName(method.getName());
methodMappingInfo.setAccessPath(path);
methodMappingInfo.setDetail(method.toString());
methodMappingInfo.setAnnotationInfo(annotation_m.toString());
methodMappingInfoList.add(methodMappingInfo);
}
}
}
interfaceInfo.setMethodInfo(methodMappingInfoList);
interfaceInfoList.add(interfaceInfo);
}
@Override
public void progressOnFailed(Class<?> clazz, int index, Throwable cause) {
lifeCLogger.debug("{} 渲染失败:{}", index, clazz.getName());
}
@Override
public void finish(int cCnt, int mCnt) {
lifeCLogger.debug("渲染完成:类个数={} 方法个数={}", cCnt, mCnt);
}
}
第二步 将实现类的实例,按下图方法设置一下即可

本文来自博客园,作者:月色深潭,交流群:733423266,转载请注明原文链接:https://www.cnblogs.com/moonpool/articles/16955819.html

浙公网安备 33010602011771号