dubbo文档覆盖优化,线程安全处理,文档优化
This commit is contained in:
@@ -8,16 +8,23 @@ dubbo文档的管理项目,支持文档自动扫描,文档展示和修改,
|
||||
后端使用spring boot,前端使用vue、element-ui、JQuery等
|
||||
|
||||
#### 安装教程
|
||||
|
||||
1. `zyplayer-doc-manage` -> `application.yml` -> `zyplayer.dubbo.zookeeper.url` 配置zookeeper地址
|
||||
|
||||
2. `zyplayer-doc-manage` -> `application.yml` -> `zyplayer.dubbo.nacos.url` 配置nacos服务地址
|
||||
|
||||
3. 默认找zookeeper,未配置再找nacos的配置,访问地址:http://127.0.0.1:8082/zyplayer-doc-manage/doc-dubbo.html
|
||||
|
||||
4. 支持文档查找、文档编辑、在线调试接口
|
||||
|
||||
5. 自动获取参数列表需要指定的类存在,所以请在 pom.xml -> dependencies 最后加上服务所在的包,后端才能通过Class.forName("xx");来找到参数列表,减少录入成本
|
||||
|
||||
6. 数组或List参数,调试参数录入格式例:[1,2] ,后端通过JSON工具转成指定类型,有不支持的类型时欢迎反馈
|
||||
|
||||
#### 文档JAR上传说明
|
||||
为了达到获取服务的类的方法信息尝试过很多方式:
|
||||
1. 比如在dubbo文档项目内,这样每次依赖的jar升级都需要重新发版
|
||||
2. 比如自动下载远程仓库或读取本地仓库的jar来获取类,但这样如果jar包里依赖了另外的jar则不可行了,需要解析整个maven依赖树,复杂度高
|
||||
3. 当前找到的最合适的方式就是一个模块依赖所有需要的jar,然后打包后传上去,这样所有的依赖都在此包里了,也不需要重新发版
|
||||
> 如果你有更好的建议欢迎提出来探讨,非常乐意接受更加方便的建议!
|
||||
|
||||
所以您需要做的是:
|
||||
1. 将所有dubbo接口依赖放到 zyplayer-doc/zyplayer-doc-other/zyplayer-doc-dubbo-libs/pom.xml 的\<dependencies>中
|
||||
2. 打包此模块:mvn package
|
||||
3. 将文件 ./zyplayer-doc-dubbo-libs/target/zyplayer-doc-dubbo-libs-x.x.x.jar 在您的dubbo文档页面上传
|
||||
> 这样每次点击方法时将读取此JAR找到类和方法信息来展示
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.zyplayer.doc.dubbo.framework.service.MgDubboStorageService;
|
||||
import com.zyplayer.doc.dubbo.framework.service.NacosDocService;
|
||||
import com.zyplayer.doc.dubbo.framework.service.ZookeeperDocService;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -158,13 +159,15 @@ public class DubboController {
|
||||
@PostMapping(value = "/getDocList")
|
||||
public DocResponseJson getDocList() {
|
||||
String dubboServiceList = mgDubboStorageService.get(StorageKeys.DUBBO_SERVICE_LIST);
|
||||
String dubboServiceDoc = mgDubboStorageService.get(StorageKeys.DUBBO_SERVICE_DOC);
|
||||
if (StringUtils.isBlank(dubboServiceList)) {
|
||||
return DocResponseJson.ok();
|
||||
}
|
||||
DubboInfoVo dubboInfoVo = new DubboInfoVo();
|
||||
List<DubboInfo> providerList = JSON.parseArray(dubboServiceList, DubboInfo.class);
|
||||
dubboInfoVo.setServerList(providerList);
|
||||
// TODO 感觉不该在这里返回,应该每次点击的时候去包里面重新找一次文档
|
||||
// 但是这样的话只存了一个大的json,容易出现覆盖问题,看来还得分接口方法一条一条记录的存,才能针对方法来修改
|
||||
String dubboServiceDoc = mgDubboStorageService.get(StorageKeys.DUBBO_SERVICE_DOC);
|
||||
if (StringUtils.isNotBlank(dubboServiceDoc)) {
|
||||
List<DubboDocInfo> docInfoList = JSON.parseArray(dubboServiceDoc, DubboDocInfo.class);
|
||||
Map<String, DubboDocInfo> docInfoMap = docInfoList.stream().collect(Collectors.toMap(DubboDocInfo::getFunction, val -> val));
|
||||
@@ -199,15 +202,26 @@ public class DubboController {
|
||||
if (dubboDocInfo == null) {
|
||||
dubboDocInfo = new DubboDocInfo();
|
||||
dubboDocInfo.setParams(definition.getParams());
|
||||
dubboDocInfo.setFunction(function);
|
||||
dubboDocInfo.setVersion(1);
|
||||
dubboDocInfo.setResultType(definition.getResultType());
|
||||
dubboDocInfo.setService(param.getService());
|
||||
dubboDocInfo.setMethod(param.getMethod());
|
||||
dubboDocInfo.setFunction(function);
|
||||
dubboDocInfo.setVersion(1);
|
||||
docInfoMap.put(function, dubboDocInfo);
|
||||
List<DubboDocInfo> docInfoList = new ArrayList<>(docInfoMap.values());
|
||||
mgDubboStorageService.put(StorageKeys.DUBBO_SERVICE_DOC, JSON.toJSONString(docInfoList));
|
||||
} else {
|
||||
// 根据参数顺序,把之前写的参数说明放到新的上面去
|
||||
if (CollectionUtils.isNotEmpty(definition.getParams()) && CollectionUtils.isNotEmpty(dubboDocInfo.getParams())) {
|
||||
for (int i = 0; i < definition.getParams().size() && i < dubboDocInfo.getParams().size(); i++) {
|
||||
DubboDocInfo.DubboDocParam dubboDocNew = definition.getParams().get(i);
|
||||
DubboDocInfo.DubboDocParam dubboDocOld = dubboDocInfo.getParams().get(i);
|
||||
dubboDocNew.setParamDesc(StringUtils.defaultIfBlank(dubboDocOld.getParamDesc(), dubboDocNew.getParamDesc()));
|
||||
}
|
||||
}
|
||||
dubboDocInfo.setParams(definition.getParams());
|
||||
dubboDocInfo.setResultType(definition.getResultType());
|
||||
}
|
||||
List<DubboDocInfo> docInfoList = new ArrayList<>(docInfoMap.values());
|
||||
mgDubboStorageService.put(StorageKeys.DUBBO_SERVICE_DOC, JSON.toJSONString(docInfoList));
|
||||
return DocResponseJson.ok(dubboDocInfo);
|
||||
}
|
||||
|
||||
@@ -277,6 +291,9 @@ public class DubboController {
|
||||
try {
|
||||
classLoadService.closeClassLoad(() -> {
|
||||
File docJarFile = new File(zyplayerDocDubboLibPath + "/" + DubboDocConst.DUBBO_DOC_LIB_NAME);
|
||||
if (docJarFile.exists()) {
|
||||
docJarFile.delete();
|
||||
}
|
||||
file.transferTo(docJarFile);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -53,8 +53,10 @@ public class ClassLoadService {
|
||||
}
|
||||
synchronized (ClassLoadService.class) {
|
||||
// file:D:/maven/repository/com/zyplayer/dubbo-api/1.0/dubbo-api-1.0.jar
|
||||
URL fileUrl = new URL("file:/" + zyplayerDocDubboLibPath + "/" + DubboDocConst.DUBBO_DOC_LIB_NAME);
|
||||
docClassLoader = new URLClassLoader(new URL[]{fileUrl}, Thread.currentThread().getContextClassLoader());
|
||||
if (docClassLoader == null) {
|
||||
URL fileUrl = new URL("file:/" + zyplayerDocDubboLibPath + "/" + DubboDocConst.DUBBO_DOC_LIB_NAME);
|
||||
docClassLoader = new URLClassLoader(new URL[]{fileUrl}, Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
}
|
||||
return docClassLoader;
|
||||
}
|
||||
@@ -77,6 +79,7 @@ public class ClassLoadService {
|
||||
docClassLoader = null;
|
||||
if (callback != null) {
|
||||
// callback方式,防止刚close,马上又被别人new出来了
|
||||
// callback主要是删除文件,如果文件被加载了应该删除和创建不了(我没测,理论上会是这样)
|
||||
callback.callback();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user