• 热门专题

希望有兴趣的加入 共同为项目智能化管理jar包而努力 第二篇

作者:mazhimazh  发布日期:2016-12-26 20:23:15
Tag标签:兴趣  项目  包而  
  •   想听听大家对于我这个想法的一些看法,喷也好,赞也罢,希望留下您宝贵的建议!  

    有共同想法并且想实现的请入群 2500261120 

      在使用autort插件时,首先要到autort服务器下载所有的jar包快照。里面存在了检索jar的相关信息。   在第一篇我们专门介绍过如何划分java类中出现的某一串字符,想了解的或者不知道我要干什么的请点这里 。其实说白了,也就是系统的整个类的组织及查询方式。Trie树可以在我们知道类全名的情况下尽快找到所需要的类。   当通过类全名找到存储某个类的Node时,此Node中有个map属性,key为类名,而值保存了这个类在版本迭代过程中的所有快照。类似于Git用快照来保存文件迭代的过程。不同的是,这里的快照是类的快照,而不是文件。类似如下形式:   一个类的不同快照会使用List列表来存储,因为版本的迭代发布本来就是有先后顺序的。快照的具体json结构如下:  
    {
       serialVersion:快照支持的一系列版本,这些版本都是连续的
       type:{
       modifiers:修饰符
       type:表示类型,如1代表类,2代表interface,3代表枚举,4为注解定义
       name:内部类的写法为outer.innter  
       extends:全类名的形式
       implements:[] 多个类全名的形式
       types:[] 存储多个type 
       fields:1[
           {
            modifiers:方法修饰符
            declType:方法返回类型,也是全类名的形式
            name:方法名称
           }
           ...
       ]
       methods:[
           {
             modifiers:方法修饰符 
             returnType:方法返回类型,也是全类名的形式
             name:方法名称
             throws:全类名的形式
             arguments:[] 多个全类名的形式
           }
           ...
       ]  
        }
    } 
    
    首先介绍一下serialVersion属性。   举个例子,spring-core从开始发布版本至今共有90个版本。假如某个类A在1.2.8版本之前一直没有变化,那么这个serialVersion代表着之前的所有版本(共25个)。   假如在2.0进行API调整或者类重构时,这个类发生了变化,也就是快照中保存的某个或者多个属性发生了变化,比如某个方法的参数类型改变了,那么需要再生成一个快照结构,代表这次的变化。假如这次重构后经历了10次版本迭代仍然没有变化,那么这个结构中的serialVersion标识这10个版本。   如果下一次重构时,这个类变换了类路径,那么它将做为相应类路径下一个新建的类开始存在。而原来的快照只保存之前的35个版本快照。   下面重点来看一下type属性。   modifiers修饰符的定义:     例如某个类的修饰符有public和final,那么modifiers的值为 PUBLIC|FINAL   extends为字符串形式,存储了这个类可能继承的其它类。如果为空,默认为Object   implements类型为数组,存储值必须为全名,以方便通过Trie树迅速查找到这些接口相关的信息。可以为空。   types属性。这个属性中存储了多个type结构,这个type结构可能是类(包括抽象类)、接口、枚举类和注解定义类。   无论这个内部的结构有什么修饰符都需要存储相关的信息。和我们后面将要提到的属性与方法略有不同,属性与方法是通过不同的修饰符选择性存储。   举个例子:  
    public class Father01 {
    	private class A{
    		public int a = 2;
    	}
    	public class B extends A{
    		
    	}
    }
    
    类A虽然是private,但是B继承了A。客户端的代码如下:  
    public class Son01 extends Father01{
    	public void test(){
    	    B b = new B();
    	    int x=b.a; // 使用了嵌套类A中声明的属性
    	}
    }
    
    但是在块内Block定义的类就不需要保存了,因为封闭性较好,通常情况下无法被外部使用。接口,枚举类与注解定义类不能在块内定义。     剩下就是fields与methods了,目前private与默认访问控制符修饰的变量与方法不建立快照相关信息。   如果程序通过反射操作了三方包中的一些类属性,那么快照中需要存储所有的方法(包括构造方法)与变量,因为反射可以获取到类所有相关的信息。这会使快照的数据量变大并且快照数量变多,目前暂不考虑。   下面来说一说方法中的throws异常吧。   修改了某个公有方法抛出的异常。由原来的某个不受检查异常变为了受检查的异常,那么这一版本jar包就已经不满足我们程序的要求了,autort会通过检测将这一版本排除在可选择范围之外。   需要说明的是,并不是修改了方法抛出的异常就会为type新建快照,但是从某个检查异常修改为另外的检查异常,即使两者之间有继承关系,也一定会建立新的快照。不会对Error与RuntimeException的异常进行信息保存与处理,因为这些异常不会让现有的一些程序出错。   如下实例:    
    public void test() throws ReflectiveOperationException,NullPointerException{  ...   }
    public void testException(){
       try {
            test();
       }catch (ReflectiveOperationException e) {
            e.printStackTrace();
       }
    }
    
      test方法新增加了一个非检查异常NullPointerException并且在testException方法中调用了这个方法,但是并不需要修改相关调用的代码。     其实我只说了需要存储哪些信息,并没有说为什么要选择性存储这些信息,我们可以思考一个问题:我们的程序使用了第三方jar包提供的相关功能,一搬情况下也就是下面几种:   (1)调用一个方法,使用new关键字创建对象时也看作调用它的构造方法,返回类型为构造方法所在的类类型。 (2)调用一个变量 (3)继承了三方的类或者实现了三方定义的接口   快照中需要存储足够的信息,当客户通过如上一种或多种方式使用了jar包功能时,可以通过扫描分析这些代码并结合快照中jar包类迭代的信息,快速找到当前代码合适的版本。     最终一个整体的存储结构大概如下图所示。

    需要说明的是,一个jar包就需要有这样的一个结构来组织和存储相关的信息,主要是考虑到不同jar包会有类全名(包路径和类名)相等的情况,更重要的是会通过这样的结构来选择性加载到内存。  
About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规