动态代理(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 实现方式之一就是 动态代理。
- 解耦,通过参数就可以判断真实类,不需要事先实例化,更加灵活多变。