SVNKit学习——wiki+简介(一)

  这篇文章是参考SVNKit官网在wiki的文档,做了个人的理解~

  首先抛出一个疑问,Subversion是做什么的,SVNKit又是用来干什么的?

  相信一般工作过的同学都用过或了解过svn,不了解的同学可以到官网看下,这里不作为本文重点。

  需要理解的概念:

    仓库(Repository):是一个特殊的结构,记录文件版本管理的状态。

    工作副本(Working Copy):本地从仓库检出的文件。

    修订版(Revision):用于记录仓库数据的变更状态,初始化版本为0,每执行一次操作版本号+1,每执行一次都会生成一个快照。

  SVN目录结构:

    每次进行提交等操作,svn并非记录所有文件的内容,而是比较智能的只记录和上一个版本不同的文件、目录。

    所以,如果你删除了某一个文件,并非完整的删除掉了,因为你在历史的修订版本中还是可以看到的。

  使用方式:

    1.利用一个svn客户端程序,比如命令行、TortoiseSVN、VisualSVN Server、各种IDE插件(Eclipse的Subclipse、Intellij IDEA的TMATE)
    2.利用特殊的客户端类库,比如SVNKit就是一个纯java操作SVN的程序

  集中管理不同的应用大约可以分为以下两种模式:

    1.适用于使用Working Copy管理的程序,程序通常以文件、目录等方式存在。

    2.不适用于Working Copy管理的程序,这里比较抽象一些,区别于文件、目录。但是这类文件的版本控制也是非常重要的。这种类型的程序使用Subversion Repository管理,保持其抽象的模型层次。

  建立一个Subversion仓库

  参考我的另一篇博客:http://www.cnblogs.com/douJiangYouTiao888/p/6116121.html

  SVNKit的结构是什么样子的?

  SVNKit学习——wiki+简介(一)

  通过上图我们可以比较明显的看出,主要包含两种操作方式:

  ①.High-Level API:针对Working Copy的一系列操作,底层实现实际调用Low-Level API。封装了多个SVN*Client,不同的操作基于不同的SVN*Client,操作方法和参数与SVN客户端命令行比较相似。

  ②.Low-Level API:针对Subversion Repository的操作,相当于操作Repository的中间驱动,它知道如何与底层协议进行交互(实际上这层API实现了底层协议)。这一层对数据结构进行了分层,表现为一个包含版本控制的、抽象复杂的树结构。

  SVNKit访问Repository所支持的协议:

  远程协议:
  ①.svn://协议(或svn+xxx,最常用的是svn+ssh)
  ②.http://协议(或https://协议)
  本地协议:
  ①.file:///协议,只支持FSFS类型的Repository

  SVNKit学习——wiki+简介(一)

 

  开始使用SVNKit

  从官网下载好SVNKit的二进制安装包后,第一步应该做什么?

  High-Level API:主要使用SVNClientManager类来创建一些了的SVN*Client实现一系列对Working Copy的操作,比如创建一个SVNUpdateClient,可以执行checkout、update、switch、export等。

  Low-Level API:主要使用SVNRepository类与Repository仓库进行交互,支持的协议都是基于SVNRepositoryFactory抽象类的具体实现,协议和实现类的关系:

protocol    SVNRepositoryFactory realization
svn://      SVNRepositoryFactoryImpl
http://     DAVRepositoryFactory
file:///    FSRepositoryFactory

  使用High-Level API的操作步骤:

  1.根据不同协议,初始化不同的仓库工厂。(工厂实现基于SVNRepositoryFactory抽象类)

//svn://, svn+xxx:// (svn+ssh:// in particular)
SVNRepositoryFactoryImpl.setup();
//http:// and https://
DAVRepositoryFactory.setup();
//file:///
FSRepositoryFactory.setup();

  2.创建一个驱动。(基于工厂),svnkit中repository所有的URL都基于SVNURL类生成,编码不是UTF-8的话,可以调用SVNURL的parseURIEncoded()方法。url可以是项目根目录、目录或文件。

SVNURL url = SVNURL.parseURIDecoded( "svn://host/path_to_repository_root/inner_path" );
SVNRepository repository = SVNRepositoryFactory.create( url, null );

  这里的URL有两种表现形式:(此处不好理解,下一篇文章会使用具体代码做解释)

  ①.不是以”/”开头,相对于驱动的绑定位置,即Repository的目录
  ②.以”/”开头,代表repository的根,相对于Repository的Root对应的目录

  3.创建一个权限验证对象

  SVN大多数操作都是具有权限访问控制的,大多数情况不支持匿名访问。

  SVNKit使用ISVNAuthenticationManager接口来实现权限的控制。

ISVNAuthenticationManager authManager;
...
SVNURL url = SVNURL.parseURIEncoded( "svn://host/path_to_repository_root/inner_path" );
SVNRepository repository = SVNRepositoryFactory.create( url , null );
//set an auth manager which will provide user credentials
repository.setAuthenticationManager(basicAuthManager);
...

  权限管理基于以下四个逻辑块:

  SVNKit学习——wiki+简介(一)

  不同类型的身份验证凭据:(要依据实际类型创建)

Kind                Class representation            Field of usage
PASSWORD            SVNPasswordAuthentication       login:password authentication (svn://, http://)
SSH                 SVNSSHAuthentication            In svn+ssh:// tunneled connections
SSL                 SVNSSLAuthentication            In secure https:// connections
USERNAME            SVNUserNameAuthentication       With file:/// protocol, on local machines

  身份验证交互示意图(图1首次、图2非首次):身份验证首次需要用户输入,后续则无需重复输入:

  图1:

  SVNKit学习——wiki+简介(一)

  图2:

   SVNKit学习——wiki+简介(一)

  代理:如果authentication manager提供了一个非空的proxy manager,SVNKit将通过代理服务器代理管理目标服务器。

  SSL:支持SSL管理

  ISVNAuthenticationManager的默认实现:

  ①.BasicAuthenticationManager:

    1.无需磁盘授权存储。

    2.无需提供SSL provider

    3.无需服务器或者文件配置。

    4.使用proxy、ssh setting、user credentials provoded到类的构造器中,无需身份验证提供者。

    5.不缓存credentials 。

  ②.DefaultSVNAuthenticationManager:

    1.可以使用磁盘一个授权存储于默认Subversion运行的配置或者指定的目录。可以在目录中缓存credentials。

    2.使用运行时的内存存储credentials。

    3.可以使用用户提供的username/password认证用户。

    4.使用SSL、SSH、Proxy setting、服务器配置文件运行Subvesion。

  强制认证方案:

  尽管Subversion的优势是你不需要重复验证直到服务器要求验证。有时它可能是有效有能力让svnkit立即验证用户不浪费时间。ISVNAuthenticationManager接口提供了这个能力,它在SVNKit使用一个行为控制时返回一个标识。

  HTTP认证的方案:

  ①.Basic

  ②.Digest

  ③.NTLM

  Basic、Digest两种方案,你需要提供一个用户名和密码:

ISVNAuthenticationManager authManager = new BasicAuthenticationManager( "login" , "password" );

  NTLM方案,你需要提供一个主域名:

ISVNAuthenticationManager authManager = new BasicAuthenticationManager( "DOMAIN//login" , "password" );

 

  
 
  

 

java学习中,成员内部类、匿名内部类(java 学习中的小记录)

java学习中,成员内部类、匿名内部类(java 学习中的小记录)java学习中,成员内部类、匿名内部类(java 学习中的小记录)作者:王可利(Star·星星)

 

内部类:

一个类中定义另外一个类,这样的类叫内部类。

内部类的文件名:外部类名$内部类名.class   java学习中,成员内部类、匿名内部类(java 学习中的小记录)

 

内部类分两种:

    1.成员内部类

        如何访问成员内部类:

            方式1:外部类中定义一个方法来创建内部类对象,再通过对象进行访问。

            方式2:可以直接在其他类中直接创建内部类这个对象,通过对象访问。用点语。

                      格式:外部类名.内部类名  对象名 = new 外部类名().new 内部类名(); 

        内部类使用的注意事项:

            1.如果外部类和内部类中有同名的成员变量,那么在内部类中java虚拟机默认访问内部类中的成员变量,可以通过格式: 外部类名.this.变量名。

            2.如果内部类中的成员被private 修饰了,那么只能用方式1 来访问内部类的成员。

            3.内部类中有变量被 static 修饰了,那么这个类也必须是一个静态的类。

        内部类使用的好处:

            内部类中是可以直接访问外部类的所有成员。实际上还是外部类自己调用的。外部类拥有内部类。

         一般什么时候使用内部类:

             我们在描述一个A对象,发现A对象中又需要有一个对象B,对象B很复杂,B对象又想访问A中的数据。这个时候用内部类来描述B对象就更方便了。

             又比如说:人有心脏,人也有血液。人是一个类,心脏是一个类,血液也是一个类。 那么心脏想访问血液的话就很麻烦。

 1 package study;
 2 
 3 class Outer {
 4     
 5     int i = 10;//自带的成员变量 外部类
 6     
 7     //定义一个内部类
 8     //成员内部类
 9     class Inner{
10         
11         int i = 20;//内部类的变量
12         
13         public void print() {
14             System.out.println("这个是内部类"+i);//打印的是20
15             System.out.println("这个是内部类"+Outer.this.i);//访问的是外部类的属性
16         }
17     }
18     //创建一个方法来创建内部类对象(方式1)
19 /*    public void instantce(){
20         //创建内部类对象
21         Inner inner = new Inner();
22         inner.print();    
23     }*/
24 }
25 //其他类
26 public class star {
27     public static void main(String[] args) {    
28 /*        //在其他类中访问内部类(方式1)
29         Outer outer= new Outer();
30         outer.instantce();*/
31         
32         //其他类中直接访问:(方式2)
33         Outer.Inner inner = new Outer().new Inner();
34         inner.print();
35         
36    }
37 }

    2.局部内部类

        局部内部类:在类方法中定义的类,这样的一个类叫局部内部类。

        局部内部类只能通过第一种方式来访问。

        局部内部类使用注意点:

            如果局部内部类访问了方法中的局部变量,方法中的局部内部类必须用final来修饰。

 1 class Outer{
 2     String name = "外部类的name";
 3     int i = 20; 
 4     
 5     public void test() {
 6         
 7         final int i = 30;//局部变量 出了这个方法就消失。
 8         //为什么要用final来修饰?
 9         /*test方法执行完,变量i 立马从内存中消失,而inner对象在方法执行完之后,没有消失的,这里再使用i就好比把i的生命周期延迟了,与局部变量的定义不符。
10          *所以用final修饰,相当于把i设置了一个复制品给test方法使用,真实的i已经消失。
11          * */
12         
13         //局部内部类
14         class Inner{
15             public void print(){
16                 /*int i = 10; 注销之后研究拿到30这个i*/
17                 System.out.println("这个是局部内部类的方法"+i);//打印的是10
18             }
19         }
20         //创建局部对象
21         Inner inner = new Inner();//test走完,这个对象可能还存在(它是由java虚拟机决定消除的,不知道是什么时候),存在的话相当于给 i 的生命周期延迟了。
22         inner.print();
23     }    
24 }
25 
26 public class Star {
27 
28     public static void main(String[] args) {
29         //在其他类中访问局部内部类
30         Outer out = new Outer();
31         out.test();
32         
33         //下面是错误的写法
34         /*Outer.Inner inner = new Outer().new Inner();
35         inner.print();*/
36     }
37 }

匿名的内部类(没有类名的类)

好处:简化书写

匿名内部类使用前提:外部类必须有继承或者实现关系。

因为它没有名字,它实际创建出来是靠父类来创建的,以多态表现出来的。所以要继承或实现关系。

它的实现实际以多态的形式表现的所以需要满足上面的条件。

匿名内部类一般用于实际参数的传递。(和匿名对象用法一样)

abstract class Animal{
    public abstract void run();
    public abstract void sleep();
}

//外部类
//在Outer里面创建一个Dog的内部类
class Outer{
    
    //不用匿名
    /*class Dog extends Animal{
        public void run() {
            System.out.println("狗在跑");
        }
        public void sleep() {
            System.out.println("狗在睡觉");
        }
    }*/
    

    public void print(){
        //Dog d = new Dog();
        //d.run();
        
        //匿名的Dog(通过父类来完成创建)
        //匿名内部类:只是没有名字,其它的和普通的类没什么不一样
        Animal a = new Animal(){//不是父类创建对象 匿名内部类(子类)
            //具体实现
            public void run(){
                System.out.println("狗在跑");
            };
            public void sleep(){
                System.out.println("狗在睡觉");
            };
        };
        a.run();
        a.sleep();
    };
}
 
public class Star {

    public static void main(String[] args) {
        Outer out = new Outer();
        out.print();
        
    }
}