畅远数码|先要对微服务进行度量,进行微服务治理( 二 )


源码是一个宝库 , 包含了很多的内容 。 假如有个“超人”能够记住所有的源码并理解透彻 , 那么很多治理的难题都能迎刃而解 。 问题一出来 , 超人就能快速地定位问题所在 。 奈何现实中没有超人 , 全盘读懂源码既是脑力活也是体力活 , 将成千上万个核心类的调用关系梳理出来并画出关系图 , 没有核心程序员好几周的辛苦努力是搞不定的 。
“人力有穷时” , 最好的办法是通过某种自动化手段 , 自动提取源码中的元素 , 自动梳理这些元素之间的关系 , 简言之就是“通过代码去理解代码” 。
所幸 , 现在已经有一些能够对源码进行解析的工具和组件 , JDT就是其中的典型代表 。 JDT的全称是JavaDevelopmentTools , 是Eclipse的核心组件 , 主要用于Java程序的组织、编译、调试和运行等 。 在Java源码解析上 , JDT提供了一个AST组件(AbstractSyntaxTree , 抽象语法树)来做Java程序分析 。 通过AST , 编译器会把代码转化成一棵抽象“语法树” , 树上的每个节点代表一个代码元素(变量、方法、逻辑块等) , 同时针对节点的类型和属性解析提供完整的能力 。
利用JDT-AST解析Java源码的基本能力展示如下所示 。
01.//获取Java源码
02.Stringcontent=read(javaFilePath);
03.//创建语法解析器
04.ASTParserparsert=ASTParser.newParser(AST.JLS4);
05.//设定解析器的源代码字符
06.parsert.setSource(content.toCharArray());
07.//使用解析器进行解析并返回AST上下文结果(CompilationUnit为根节点)
08.CompilationUnitresult=(CompilationUnit)parsert.createAST(null);
09.//获取类型
10.Listtypes=result.types();
11.//取得类型声明(可能有多个类定义)
12.TypeDeclarationtypeDec=(TypeDeclaration)types.get(0);
13.//取得包名
14.PackageDeclarationpacketDec=result.getPackage();
15.//取得类名
16.StringclassName=typeDec.getName().toString();
17.//取得函数(Method)声明列表
18.MethodDeclarationmethodDec[]=typeDec.getMethods();
19.//取得函数(Field)声明列表
20.FieldDeclarationfieldDec[]=typeDec.getFields();
21.//继承的类或者实现的接口
22.for(Objectobj:typeDec.superInterfaceTypes()){
23.System.out.println("interface:"+obj);
24.}
25.System.out.println("extends:"+typeDec.getSuperclassType());
26.//输出包名
27.System.out.println("包名:"+packetDec.getName());
28.//输出类名
29.System.out.println("类名:"+className);
30.//输出引用import
31.System.out.println("引用import:");
32.for(Objectobj:result.imports()){
33.ImportDeclarationimportDec=(ImportDeclaration)obj;
34.System.out.println(""+importDec.getName());
35.}
36.
37.//循环输出变量
38.for(FieldDeclarationfieldDecEle:fieldDec){
39.for(Objectobj:fieldDecEle.fragments()){
40.System.out.println("类变量:"+fieldDecEle.getType()+""+((VariableDeclarationFragment)obj).getName());
41.}
42.}
43.for(MethodDeclarationmethod:methodDec){
44.System.out.println("方法:"+method.getName());
45.//遍历方法内变量
46.ListmParams=method.parameters();
47.if(mParams!=null){
48.for(inti=0;i<mParams.size();i++){