您的位置:首页 > 其它

设计模式 —— 动态代理(Dynamic Proxy)

2016-06-21 10:30 423 查看

动态代理(Dynamic Proxy)

静态代理的缺点:

静态代理 是有缺点的,看下图。



我们为每个类实现代理,但代理的内容却可能是相同的,比如一个项目中的日志代理,对象缓存代理等等。为每个类实现代理大大提高了代码量,可能会变得难以控制。

动态代理:

用一句话来简单概述:动态代理按功能固定代理类,动态的更换 代理类中的被代理对象。

静态代理不固定代理类,为每个被代理对象创建代理类。

动态代理类固定了代理类,通过反射来动态的为每个对象代理。



例子:

给两个对象增加日志功能

package Reflect;

import java.lang.reflect.*;

/**
* Created by andy.wwh on 2016/6/20.
*/

/*
* 对象 1
* */
interface Subject {
public String say(String name, int age);
}

class RealSubject implements Subject{
public String say(String name, int age) {
return "姓名:" +name + " 年龄:" + age;
}
}

/*
* 对象 2
* */
interface SubjectTwo {
public String say(double height, int weight);
}

class RealSubjectTwo implements SubjectTwo {
public String say(double height, int weight) {
return "身高:" + height + " 体重:" + weight;
}
}

class MyInvocationHandler implements InvocationHandler {
private Object object = null;

/*
* 绑定不同的对象,代理类不变,对象改变
* */
public Object bind(Object object) {
this.object = object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
}

/*
* 日志代理功能
* */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("日志:打印信息");
//要通过反射来实现
Object temp = method.invoke(this.object, args);
return temp;
}
}

public class hello {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
MyInvocationHandler proxy = new MyInvocationHandler();
//代理对象 1
Subject sub = (Subject) proxy.bind(new RealSubject());
System.out.println(sub.say("wwh", 21));
//代理对象 2
SubjectTwo subTwo = (SubjectTwo) proxy.bind(new RealSubjectTwo());
System.out.println(subTwo.say(1.86, 75));
//即使是更换对象的方法也会打印信息
}
}




优点:

Proxy 类的代码被固定下来,不会因为业务的逐渐庞大而改变。

可以实现AOP编程,Spring 的 AOP 实现方式之一就是 动态代理

解耦,通过参数就可以判断真实类,不需要事先实例化,更加灵活多变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: