史上最形象易懂的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,表示返回该类的对象,结果与第一种相同。
以上是本人的拙见。