java代理模式和动态代理实例代码讲解



java设计模式中的代理模式:就是当调用代理者的某个方法时,代理者在自己内部调用被代理者的相应方法,看起来就像代理者自己执行的某个方法样。代理者和被代理者实现同一个接口。

举例:例如朝鲜(NorthKorea)和美国(America)没有建立外交关系,朝鲜对美国喊话(Speak),要通过代理者瑞士Swiss来实现。

/**
*
* @author man
* 定义一个国家接口.包含国家的共同属性和方法
*/
public interface Country {
public void SpeakToAmerica(String message);//同美国对话

}/**
*
* @author man
* 瑞士,作为中间代理.将朝鲜想说的话,传达给美国
*/

public class Swiss implements Country{

private Country country = null;
public Swiss(){
this.country = new NorthKorea();
}
@Override
public void SpeakToAmerica(String message) {
this.country.SpeakToAmerica(message);

}

}

public void proxyTest(){//代理模式 测试
Swiss swiss = new Swiss();
String message = “放弃美韩联合军演,我就停止铀浓缩活动”;
swiss.SpeakToAmerica(message);//看起来是瑞士说话,其实是朝鲜在说话.瑞士只是在代理朝鲜,真正说话的是朝鲜
}

以上就是设计模式中的代理模式,关键点就是代理者和被代理者实现同一个接口,代理者被调用,代理者内部又调用被代理者。发现没,这样的话一个代理者只能代理实现一个接口,如果我要代理多个接口的实现呢,那代理者是不是也要相应的增加,那样代码就会过度膨胀,有一个方法,动态代理。

 

与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。

动态代理示例:

定义接口;


public interface Man {
public void showMsg(String msg);
}

public interface Man {
public void showMsg(String msg);
}

定义该接口的实现类:

public class Man1 implements Man {

@Override
public void showMsg(String msg) {
System.out.println(msg);

}

}

动态代理代理类:

public class MyInvocationHandler implements InvocationHandler{
private Object obj;

//绑定一个委托对象,并返回一个代理类
public Object bind(Object obj){
this.obj = obj;
return Proxy.newProxyInstance(this.obj.getClass().getClassLoader(), this.obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object obj, Method method, Object[] args)
throws Throwable {
Object tmp = method.invoke(this.obj, args);//运用反射机制,调用method方法
return tmp;
}

}

测试:

/**
*
* @author man
* 动态代理的实现,运用反射机制
*/
public class DynamicProxy {
public static void main(String[] args){
MyInvocationHandler handler = new MyInvocationHandler();
Man man1 = new Man1();
<span style=”color:#ff0000;”>Man proxy_man = (Man)handler.bind(man1);</span>
proxy_man.showMsg(“hhhhhhhhhhh”);
}
}

红色部分相当于之前的代理模式的实现,看到了吧,如果要代理多个接口的话,不需要像之前那样新增多个代理类了,而是直接将要实现的接口的实例作为参数绑定到InvocationHandler中,就动态生成了一个代理类。