代理模式(Proxy Pattern),一个类代表另一个类的功能。这种类型的设计模式属于结构型模式的一种。
意图:为其他对象提供一种代理以控制对这个对象的访问。
解释:就好像明星一般都是由经纪人接替管理明星的工作。一般工作都是通过经纪人才能对明星进行访问
实现:代理模式有静态代理和动态代理,动态代理又有JDK代理和cglib代理
源码:
静态代理:
public interface TestAdd(){
int add(int a, int b);
}
public class TestAddImpl implements TestAdd(){
int add(int a, int b){
return a+b;
}
}
public class TestAddProxy implements TestAdd(){
private TestAdd testAdd;
TestAddProx(TestAdd testAdd){
this.testAdd = testAdd;
}
int add(int a, int b){
//具体执行前可以做的工作
int result = testAdd.add(a, b);
//具体执行后可以做的工作
return result ;
}
}
上面的代码属于静态代理。在代码中,我们定义了一个接口TestAdd,一个具体实现类TestAddImpl和一个代理类TestAddProxy。在真正调用代理类的方法前后,我们可以做一些操作
缺点:静态代理是为每个被代理的对象构造相应的代理类,然后重复地写很多类似的代码。
动态代理:
JDK动态代理利用java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力
public class TestAddProxy implements InvocationHandler {
private Object obj;
public Object getProxy(Object obj) {
this.obj= obj;
//取得代理对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), this); //标记1
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
this.doBefore();
result=method.invoke(target, args);
this.doAfter();
return result;
}
public void doBefore(){}
public void doAfter(){}
}
由标记1我们可以看出在使用JDK代理时需要使用到接口的实现类
Cglib动态代理(使用前导入包):
public class TestAddProxy implements MethodInterceptor{
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
//设置需要创建子类的类
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
//通过字节码技术动态创建子类实例
return enhancer.create();
}
//实现MethodInterceptor接口方法
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
this.doBefore();
Object result = proxy.invokeSuper(obj, args);
this.doAfter();
return result;
}
public void doBefore(){}
public void doAfter(){}
}
cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理
动态代理是动态生成具体委托的代理类实现对象,它并不需要为各个委托类逐一实现代理类.