史上最形象易懂的java代理

1,什么是java代理

  一个事物的产生不是没有原因的,就像是艺术源于生活却又高于生活。这里不会给大家冷冰冰的定义,理解java代理就从生活中找例子。java代理就像是明星身边的经纪人、买东西时的代购人、老板身边的助理等等,一说这些想必大家都懂java代理是用来干什么的了吧。就是原本自己可以做却不想做或者说自己做代价太大,从而找个人帮自己做。一个篱笆三个桩,一个好汉三个帮嘛。但是有一点,经纪人啥的只是帮你忙的,真正核心的事情还是要自己做,歌手的经纪人可以帮歌手安排演唱会,但是唱歌的只能是这个歌手。代购人可以帮你买东西,但是付钱的只能是你,助理可以拿文件给老板,但签字的一定是老板。

2,实例详解java代理

  java代理分为静态代理和动态代理。本人非常喜欢NBA,就拿NBA的来举例子。杜兰特绝对算是今年NBA市场的一条的大鱼,许多球队都想与杜兰特探讨签约问题,但是杜兰特不擅长或者不想亲自与这些球队进行探讨,那么他就需要一个经纪人,这个经纪人就会为杜兰特来处理这些事。

  首先杜兰特是超级巨星,他的合同就应该符合超级巨星的合同。

public interface Superstar {
    void Play();//个人能力
    void Team();//团队贡献
}

 

以上是一个命名为Superstar的接口,接口是一套行为规范,也就是说一个超级巨星应该符合的条件。

public class DuLanTe implements Superstar {
    @Override
    public void Play() {
        System.out.println("我打球贼好");
    }

    @Override
    public void Team() {
        System.out.println("我是精神领袖");
    }
}

 

建立一个DuLanTe类实现这个接口表明自己是超级巨星的身份,实现里面的方法用来说明自己是货真价实。

以下是静态代理

public class DuLanTeProxy1 implements Superstar{//静态代理,杜兰特的专属代理
    DuLanTe du = new DuLanTe();
    @Override
    public void Play() {
        System.out.print("杜兰特的打球水平:");
        du.Play();
    }

    @Override
    public void Team() {
        System.out.print("杜兰特的团队增益:");
        du.Team();
    }
}

 

这个静态代理的意思是,这个代理是杜兰特的专属代理,只做杜兰特一个人的经纪人。

实现Superstar接口,我有为超级巨星做经纪人的资格。

里面新建了一个DuLanTe对象,表明这个经纪人是为杜兰特做代理的。

实现接口中的两个方法表明,你可以通过我去了解杜兰特的情况。

public static void main(String[] args){
        SignDulante1();//我想签约杜兰特
    }

    public static void SignDulante1(){
        DuLanTeProxy1 duLanTeProxy1 = new DuLanTeProxy1();
        duLanTeProxy1.Play();
        duLanTeProxy1.Team();
    }

 

结果:

杜兰特的打球水平:我打球贼好
杜兰特的团队增益:我是精神领袖

 

以下是动态代理的第一种方式:

public class DuLanTeProxy2 {//动态代理,临时从代理公司招代理
    DuLanTe duLanTe = new DuLanTe();
    
    public Superstar getProxy(){
        return (Superstar) Proxy.newProxyInstance(
                DuLanTeProxy2.class.getClassLoader(),//经纪人所属的经纪人公司
                duLanTe.getClass().getInterfaces(),  //经纪人所要实现的接口
                new InvocationHandler() {            //经纪人要干的是事情
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("想了解杜兰特的情况先找我");
                        method.invoke(duLanTe,args);
                        System.out.println("了解完情况,你可以走了");
                        return null;
                    }
                });
    }
}

 

动态代理就不是专属代理了,而是从经纪人公司临时找一个经纪人。

这个类其实就是一个经纪人公司,里面有一个getProxy()方法用于获得一个经纪人。

Proxy.newProxyInstance()方法用于获得一个经纪人。该方法一共三个三个参数,分别是:经纪人所属的公司,经纪人的资格(就是实现的接口),经纪人所做的事情。
其中最后一个参数,经纪人所做的事情new一个匿名内部类有一个方法具有三个参数(代理对象本身,被代理对象的方法(杜兰特),方法的参数)。
public static void main(String[] args){
        SignDulante2();//我想签约杜兰特
    }
public static void SignDulante2(){
        DuLanTeProxy2 duLanTeProxy2 = new DuLanTeProxy2();
        Superstar proxy = duLanTeProxy2.getProxy();
        proxy.Play();
        proxy.Team();
    }

 

结果
想了解杜兰特的情况先找我
我打球贼好
了解完情况,你可以走了
想了解杜兰特的情况先找我
我是精神领袖
了解完情况,你可以走了
以下是动态代理的第二种方式:
public class DuLanTeProxy3 implements InvocationHandler {
    DuLanTe duLanTe = new DuLanTe();
    public Superstar getProxy(){
        return (Superstar)Proxy.newProxyInstance(
                DuLanTeProxy3.class.getClassLoader(),//所属的经纪人公司
                duLanTe.getClass().getInterfaces(),  //所实现的接口
                this
                //因为这个类本身实现了InvocationHandler接口(知道自己应该做的事),只需要填写该类的对象即可。
        );
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("想了解杜兰特的情况先找我");
        method.invoke(duLanTe,args);
        System.out.println("了解完情况,你可以走了");
        return null;
    }
}

 

经纪人公司直接实现InvocationHandler接口定义好该公司的经纪人要做什么事。返回代理类时,在“经纪人要做的事情”这个参数上直接写this,表示返回该类的对象,结果与第一种相同。

以上是本人的拙见。

 

posted @ 2019-07-04 18:45  爱鑫一击  阅读(230)  评论(0编辑  收藏  举报