设计模式之代理模式
一、目的
代理模式的目的就是为了增强,言外之意就是为了使代理的对象或接口具有更丰富的功能。代理模式分为静态代理和动态代理两种。
二、静态代理
静态代理实质上是需要代理持有一个目标对象,并对目标对象进行增强。这样一来,当需要代理的对象数量很多时,就会在代理中产生很多的目标对象,对于代理类来说不灵活,而且显得臃肿。
- 目标接口
package com.zero.proxy;
/**
* 目标接口
*/
public interface TargetInterface {
void action();
}
- 实现类
package com.zero.proxy;
public class TargetImpl implements TargetInterface {
@Override
public void action() {
System.out.println("do real action");
}
}
- 代理类
package com.zero.proxy;
/**
* 代理类需要跟真实的实现类一样,实现代理的接口
*
*/
public class StaticProxy implements TargetInterface {
//代理的目标接口
private TargetInterface targetInterface;
public StaticProxy(TargetInterface targetInterface) {
this.targetInterface = targetInterface;
}
@Override
public void action() {
//代理逻辑
System.out.println("do proxy.");
//原有逻辑
targetInterface.action();
}
}
动态代理
为了减少代理类持有大量的代理对象,所以就需要动态代理,动态代理根据反射可以动态的获取代理的接口方法,并加以增强。动态代理需要实现InvocationHandler接口
- 动态代理类
package com.zero.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 使用jdk动态代理实现,jdk动态代理主要实现步骤:
* 1、实现InvocationHandler接口,并重写invoke()
* 2、提供构造方法,实例化目标对象
* 3、调用目标对象方法
*/
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("do dynamic proxy");
return method.invoke(target,args);
}
}
- 测试类
package com.zero.proxy;
import java.lang.reflect.Proxy;
/**
* 代理测试类
*
*/
public class TestProxy {
public static void main(String[] args) {
// static
TargetInterface target = new TargetImpl();
/*ProxyTarget proxy = new ProxyTarget(target);
proxy.action();*/
// dynamic
//classloader, target interface, handler
DynamicProxy handler = new DynamicProxy(target);
Class clazz[] = new Class[]{TargetInterface.class};
ClassLoader classLoader = target.getClass().getClassLoader();
TargetInterface dynamicProxy = (TargetInterface)Proxy.newProxyInstance(classLoader, clazz, handler);
dynamicProxy.action();
}
}