代理模式学习
简介
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
- 作用
- 代理模式的作用是,为其他对象提供一种代理,在不改变接口的前提下,以控制对这个对象的访问
- 角色
- 代理模式一般涉及到3个角色:抽象角色(接口)、代理角色、被代理角色
- 类型
- 静态代理、动态代理(jdk代理、CGLIB代理)
静态代理
代理类、被代理类需要实现相同的接口,或者继承相同的父类
-
接口
package cn.proxy.statictest; public interface Person { void say(); }
-
被代理类
package cn.proxy.statictest; public class Chirld implements Person { @Override public void say() { System.out.println("i am liangzilun"); } }
-
代理类
package cn.proxy.statictest; public class ChirldProxy implements Person { private Person p; public ChirldProxy(Person p) { this.p = p; } @Override public void say() { System.out.println("i am heizi"); p.say(); } }
-
测试类
package cn.proxy.statictest; public class StaticProxyTest { public static void main(String[] args) { ChirldProxy chirldProxy = new ChirldProxy(new Chirld()); chirldProxy.say(); } }
可以看到可以在不改变 被代理类的情况下,增加一些功能。
- 缺陷
- 被代理类须已经存在,而且作为代理类的内部属性
- 每个业务类都要一个代理类,如果业务量庞大,会导致类急剧膨胀
- 如果接口修改,代理类和被代理类也需要跟着修改,不易维护。
动态代理(JDK代理)
-
代理类是在程序运行期间由JVM根据反射等机制动态生成的。
-
被代理类须实现接口
-
接口类
package cn.proxy.dynamicproxy; public interface Person { void say(); }
-
被代理类
package cn.proxy.dynamicproxy; public class Chirld implements Person { @Override public void say() { System.out.println("i am liangzilun"); } }
-
jdk代理
package cn.proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; 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("i am heizi"); method.invoke(target,args); return null; } // 返回动态代理 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) public <T> T getProxy(){ return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } }
-
测试
package cn.proxy.dynamicproxy; public class DynamicProxyTest { public static void main(String[] args) { DynamicProxy dynamicProxy = new DynamicProxy(new Chirld()); Person proxy = dynamicProxy.getProxy(); proxy.say(); } }