您的位置:首页 > 其它

代理模式proxy (静态代理、动态代理)

2011-06-27 10:38 357 查看
1. 代理模式的原理,其实就是类的组合,静态代理和动态代理都是一样的。

2. 代理一般可以用2种方式,一是继承, 二是组合

2.1 方式一

class A {

void a() {}

}

class B extend A {

void a() {

// 前面的处理

super.a();

// 后面的处理

}

}

2.2 方式二

class A {

void a() {}

}

class B {

A a ;

void a() {

// 前面的处理

a.a();

// 后面的处理

}

}

方式二要比方式一好, 理由是继承的耦合度太高,不如一修改,如果被代理类变了,代理类立马要变

下面是例子

------------------------------------



1.抽象角色

声明真实对象和代理对象的共同接口(租房接口)

2.代理角色(中介 租房接口)

代理对象角色内部含有对象真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口,以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他操作(收点费用),相当于对真实对象进行封装

3.真实角色(房主 租房接口)

代理角色所代表的真实对象,是我们最终要引用的对象

静态代理缺点

1.真实的角色必须存在

2.一个真实的角色必须对应一个代理角色,如果大量使用会导致类急剧的膨胀

解决缺点采用动态代理

动态代理 一个proxy可以代理100个真实的对象
静态代理 100个proxy代理100个真实对象

-----------------------------------------------------

静态代理

// 抽象角色

public abstract class Subject {

public abstract void request();

}

// 代理角色

public class ProxySubject extends Subject {

private ReadSubject readSubject;

public void request() {

//加在前面的操作

this.preRequest();

if(null == readSubject){

readSubject = new ReadSubject();

}

//真正的对象(被代理对象的方法)

readSubject.request();

//加到后面的操作

this.postRequest();

}

private void postRequest(){

System.out.println("post request");

}

private void preRequest(){

System.out.println("pre request");

}

}

// 真实的角色

public class ReadSubject extends Subject {

public void request() {

System.out.println("From real subject");

}

}

// 客户端测试

public class Client {

public static void main(String[] args) {

Subject subject = new ProxySubject();

subject.request();

}

}

----------------------------------------

动态代理

// 抽象角色

public interface Subject {

public void request();

}

// 动态代理角色(万能代理)

public class DynamicSubject implements InvocationHandler {

private Object object;

public DynamicSubject(Object object){

this.object = object;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

System.out.println("before calling" + method);

method.invoke(object, args);

System.out.println("after calling" + method);

return null;

}

}

// 真实的角色

public class RealSubject implements Subject {

public void request() {

System.out.println("from real subject!");

}

}

// 客户端测试

public class Client {

public static void main(String[] args) {

RealSubject realSubject = new RealSubject();

InvocationHandler handler = new DynamicSubject(realSubject);

Class<?> classType = handler.getClass();

/**

*

* realSubject.getClass().getInterfaces() :得到真实角色实现的接口

* param1:classType.getClassLoader():类的加载器,随便什么类的加载器都是可以的

* handler:实现InvocationHandler的控制类,它来控制到底代理那个真实的角色,在handler中可以切换真实角色

*/

Subject subject = (Subject)Proxy.newProxyInstance(classType.getClassLoader(),

realSubject.getClass().getInterfaces(), handler);

/**

1.动态生成的实例

public class $Proxy0 implements Subject{

//实现方法

public void request() {

// 利用反射的机制,得到方法

Method method = Subject .getClass().getMethod();

handler.invoke(this, method, 参数 );

}

}

*/

subject.request();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: