JAVA笔记——代理模式
来源:互联网 发布:mac安装flash失败 编辑:程序博客网 时间:2024/06/06 00:26
- 什么是代理
- 静态代理
- JDK实现动态代理
- cglib动态代理
什么是代理
举个生活中的例子:有时候我们想要买火车票,但是火车站太远,那么我们可以去附近的火车票代售点进行购买。此时,代售点就是代理,它拥有被代理对象的部分功能——售票功能。
而在编程中,代理类同样拥有被代理类部分功能,但是不仅如此,代理类可以在此基础之上附加一些自己的功能
代理类最常见的用法就是日志功能:在被代理类执行方法之前,写下日志。
静态代理
需求:
现有一只鸟,它有一个fly方法,我们想在它fly的时候,写下日志
先写一个flyable接口:
public interface Flyable { void fly();}
写一个bird,实现接口
public class Bird implements Flyable { @Override public void fly() { System.out.println("bird is flying...."); }}
写一个日志代理类,注意,代理类也要实现同样的接口
public class LogProxy implements Flyable { private Flyable f; public LogProxy(Flyable f){ this.f = f; } @Override public void fly() { System.out.println("log is writing..."); f.fly(); System.out.println("over..."); }}
测试:
public static void main(String[] args) { Bird bird = new Bird(); Flyable f = new LogProxy(bird); f.fly(); }
结果:
静态代理的缺陷也很明显,它只能代理实现了相同接口的类。随着系统业务的增长,需要代理的类可能非常多,那我们也要写非常多的代理类
因此,我们需要动态代理
JDK实现动态代理
JDK为我们提供了动态代理的能力。动态代理的优势在于,它不依赖于任何接口或类
我们先写好一个flyable和bird
public interface Flyable { void fly();}
public class Bird implements Flyable { @Override public void fly() { System.out.println("bird is flying...."); }}
JDK的动态代理,我们需要实现接口InvocationHandler,例如我们写一个日志的动态代理
public class LogHandler implements InvocationHandler { private Object target; public LogHandler(Object target) { super(); this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("log is writing..."); method.invoke(target, null); System.out.println("over..."); return null; }}
从上面代理类也可以看出,它不依赖于任何的类和接口
测试:
public class Test { public static void main(String[] args) { Bird bird = new Bird(); InvocationHandler h = new LogHandler(bird); Class<?> cls = bird.getClass(); ClassLoader loader = cls.getClassLoader(); Flyable f = (Flyable) Proxy.newProxyInstance(loader, cls.getInterfaces(), h); f.fly(); }}
结果:
JDK的动态代理也有一定的缺陷,它要求被代理的类必须实现某个接口,也就是说,JDK的动态代理是根据接口来实现的
cglib动态代理
除了JDK动态代理,我们也可以使用cglib来实现,二者的却别在于:cglib的动态代理是根据类来实现的,JDK的是根据接口来实现的
写一个bird类,有fly方法
public class Bird { public void fly(){ System.out.println("bird is flying..."); }}
代理类:实现MethodInterceptor接口。cglib创建的代理类事实上是被代理类的子类,使用Enhancer来创建
public class LogProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); /** * 创建代理类 * @param cls * @return */ public Object getProxy(Class cls){ //设置父类 enhancer.setSuperclass(cls); enhancer.setCallback(this); //创建子类 return enhancer.create(); } /** * 拦截目标类的方法 * 参数: * obj 被代理的对象 * m 被代理的对象的方法 * args 方法的参数 * proxy 代理类实例 */ @Override public Object intercept(Object obj, Method m, Object[] args, MethodProxy proxy) throws Throwable { //此处我们可以做日志等操作 System.out.println("log ......."); //cglib创建的代理类其实是被代理类的子类,此处执行父类的方法,即执行被代理类真正要执行的方法 proxy.invokeSuper(obj, args); return null; }}
测试:
public class Test { public static void main(String[] args) { LogProxy proxy = new LogProxy(); Bird bird = (Bird) proxy.getProxy(Bird.class); bird.fly(); }}
结果:
0 0
- JAVA笔记——代理模式
- 学习笔记——JAVA设计模式<6>代理模式
- Java代理模式笔记
- java代理模式——动态代理
- 设计模式学习笔记—代理模式
- Java——代理模式
- 【Java】——代理模式
- 《Java与模式》学习笔记:设计模式——代理(Proxy)模式
- 代理模式(静态代理+动态代理)——JAVA
- 代理模式笔记(Java)
- Java学习笔记-代理模式
- java设计模式——代理模式
- java设计模式——代理模式
- java设计模式——代理模式
- JAVA设计模式——代理模式
- Java设计模式——代理模式
- Java设计模式——代理模式
- java设计模式——代理模式
- ES6--Symbol
- DeviceIoControl
- weak_ptr解决shared_ptr环状引用所引起的内存泄漏
- j2se笔记 封装
- TCP/IP与HTTP相关总结
- JAVA笔记——代理模式
- 通过scanner实现日期格式的数据输入
- linux mail命令用法浅析
- (int)和int.para 和int.trypara和convert.int类型的区别
- xml三种解析
- 网页错误页提示码汇总及使用示例
- formdata 上传文件
- 欢迎使用CSDN-markdown编辑器
- Linux下让进程在后台可靠运行的几种方法(nohup/&)和前后台运行程序切换