代理模式
一个类拥有另一个类的功能。
介绍
意图:
- 为类提供一种代理以控制对这个类的访问
使用场景:
- 访问一个类时想做一些访问控制
关键代码
- 目标类和代理类相结合
优点:
- 保护目标对象
- 扩展性高
- 职责清晰
缺点:
- 处理速度变慢
- 实现可能会比较复杂
注意:
- 与装饰器模式区别:
1.侧重于访问控制
2.侧重于自己增加功能
使用
- 静态代理
/** * 具体功能 * @author 98543 */ public interface Func { public void work(); public void eat(); } /** * 具体对象 * @author 98543 */ public class Targer implements Func{ @Override public void eat() { System.out.println("走啊,去吃饭"); } @Override public void work() { System.out.println("走啊,去工作"); } } /** * 代理对象 * @author 98543 */ public class Worker implements Func{ private Targer laozong; private Vistor vistor; public Worker(Targer laozong,Vistor vistor) { this.laozong = laozong; this.vistor = vistor; } @Override public void eat() { System.out.println(vistor.getName()+"约老总去吃饭了"); laozong.eat(); System.out.println("他想 ->"+vistor.getWhat()); } @Override public void work() { System.out.println(vistor.getName()+"约老总去工作了"); laozong.work(); System.out.println("他想 ->"+vistor.getWhat()); } } // 静态代理 Vistor vistor = new Vistor("张三","目的很纯粹啊"); Targer MrLi = new Targer(); Worker wk = new Worker(MrLi, vistor); wk.eat(); wk.work(); // 输出 张三约老总去吃饭了 走啊,去吃饭 他想 ->目的很纯粹啊 张三约老总去工作了 走啊,去工作 他想 ->目的很纯粹啊
- jdk动态代理
/** * 具体功能 * @author 98543 */ public interface Func { public void work(); public void eat(); } /** * 具体对象 * @author 98543 */ public class Targer implements Func{ @Override public void eat() { System.out.println("走啊,去吃饭"); } @Override public void work() { System.out.println("走啊,去工作"); } } /** * 代理对象 * @author 98543 */ public class Doctor implements InvocationHandler{ private Targer laozong; public Doctor(Targer laozong) { this.laozong = laozong; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("1"); Object obj = method.invoke(laozong, args); System.out.println("2"); return obj; } } // jdk动态代理 Doctor doctor = new Doctor(MrLi); Func func = (Func) Proxy.newProxyInstance(Vistor.class.getClassLoader(), new Class[] {Func.class}, doctor); func.eat(); // 输出 1 走啊,去吃饭 2
- cglib动态代理
/** * 具体对象 * @author 98543 */ public class CglibTarget { public void drink() { System.out.println("百事可乐"); } } // 代理类 public class CglibProxy implements MethodInterceptor{ @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("第一步"); Object obj = arg3.invokeSuper(arg0, arg2); System.out.println("第二步"); return obj; } } // cglib动态代理(无需实现接口) Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Sample.class); enhancer.setCallback(new CglibProxy()); Sample sample = (Sample) enhancer.create(); sample.eat(); // 输出 第一步 yaxiyalei 第二步
jdk:
基于反射,效率较慢,只能基于接口实现代理。
cglib(注意jar包冲突问题):
基于字节码,依赖于asm库,无需实现也可代理,使用继承实现代理,会生成一个子类,所以不能对final修饰的方法或类进行代理。
来源:https://www.cnblogs.com/kungFuPander/p/11474925.html