代理模式详解
一、静态代理与动态代理
代理模式
使用一个代理对象将目标对象包装起来,凡是对这个目标对象方法的调用都必须通过代理对象调用,需要被代理类与代理类实现同一个接口(有相同的方法)
静态代理
编译期间就确定好代理对象,被代理类与代理类已经固定
动态代理
运行期间通过反射动态的创建目标类的代理对象,代理类与被代理类不固定
Class Proxy
//Proxy类中的newProxyInstance方法可以创建代理对象
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
param1:被代理类的类加载器
param2:被代理类实现的接口
param3:InvocationHandler的对象
二、静态代理代码实现
//所要实现的接口
interface ClothFactory {
void produceCloth();
}
//被代理类
class NikeClothFactory implements ClothFactory {
@Override
public void produceCloth() {
System.out.println("执行被代理类的方法");
}
}
//代理类
class ProxyClothFactory implements ClothFactory {
private ClothFactory factory; //拿被代理的类对象赋值(多态)
public ProxyClothFactory(ClothFactory factory) {
this.factory = factory;
}
@Override
public void produceCloth() {
factory.produceCloth(); //调用被代理对象的方法
}
}
//测试类
public class StaticProxy {
public static void main(String[] args) {
//创建被代理类的对象
ClothFactory nike = new NikeClothFactory();
//创建代理类的对象
ClothFactory proxyClothFactory = new ProxyClothFactory(nike);
//执行的是被代理类的方法
proxyClothFactory.produceCloth(); //执行被代理类的方法
//特点:代理类和被代理类在编译期间就确定下来了
}
}
三、动态代理代码实现
//要实现的接口
interface Human {
void eat(String food);
}
//创建不同代理类的工厂
class ProxyFactory{
/**
* @param obj 被代理类的对象
* @return 动态创建的对应的代理类对象
*/
public static Object getProxyInstance(Object obj) {
//创建一个类实现了InvocationHandler接口,并创建此类对象
InvocationHandler handler = new MyInvocationHandler(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), handler);
}
}
//实现InvocationHandler接口
class MyInvocationHandler implements InvocationHandler {
//当代理类对象调用某个方法时,就会自动的调用如下方法
//故应当将被代理类要执行的方法声明在invoke()中
/**
* @param method 被代理类要执行方法的Method类型
* @param args 被代理类要执行方法的参数
* @return 被代理类要执行方法的返回值
*/
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
Object value = method.invoke(obj, args);
return value;
}
private Object obj; //使用被代理类的对象赋值
public MyInvocationHandler(Object obj) {
this.obj = obj;
}
}
//被代理类
class SuperMan implements Human {
@Override
public void eat(String food) {
System.out.println("我喜欢吃" + food);
}
}
//测试类
public class ProxyTest {
public static void main(String[] args) {
//被代理类的对象
SuperMan superMan = new SuperMan();
//代理类的对象
Human proxyInstance = (Human)ProxyFactory.getProxyInstance(superMan);
proxyInstance.eat("土豆"); //我喜欢吃土豆
}
}