代理模式Proxy
问题提出:benchMark 性能测试,不修改原来代码,记录代码的运行时间:
- **继承实现:**类爆炸
- **手动组合:**自己使用代理类包装,代理类里面调用被代理对象,附加上自己的事情。
- 实现同一个接口可以实现代理的嵌套,当需要实现多个代理功能的时候
- 限制就是要实现同一个接口
- 实现同一个接口可以实现代理的嵌套,当需要实现多个代理功能的时候
- 全能代理:不同接口,解耦,动态代理,运行时候生成。
- **java.lang.reflect.Proxy **:通过反射getClass(Loader),不需要读取源码,只需要二进制字节码就得到属性和方法。
- 被代理类需要有接口:代理遵循接口才能伪装为服务的对象,让外界调用接口即可,我们负责替换
- cglib:底层也是asm。但是其实是生成了一个被代理类的子类,所以当一个类是final的时候,是不可以使用这个来实现代理的
- asm:甚至可以代理final,因为直接修改二进制字节码,所以随意
- 注意字节码class文件是二进制的,使用IDE打开的时候是显示反编译之后的代码,其实不是文件真正存放的内容
- **java.lang.reflect.Proxy **:通过反射getClass(Loader),不需要读取源码,只需要二进制字节码就得到属性和方法。
静态代理–自己包装
被包装和包装类都要实现一样的接口,
构造的时候都使用接口作为形参,传递实参的时候使用接口的具体实现类
代理类中调用的时候都使用面向接口调用,运行时候根据函数的参数替换为具体的实现类
1 | interface Movable { |
1 | package com.deltaqin.designPattern.d08_proxy; |
- Subject:程序中的业务接口,定义了相关的业务方法。
- RealSubject:实现了 Subject 接口的业务实现类,其实现中完成了真正的业务逻辑。
- Proxy:代理类,实现了 Subject 接口,其中会持有一个 Subject 类型的字段,指向一个 RealSubject 对象。
在使用的时候,会将 RealSubject 对象封装到 Proxy 对象中,然后访问 Proxy 的相关方法,而不是直接访问 RealSubject 对象。在 Proxy 的方法实现中,不仅会调用 RealSubject 对象的相应方法完成业务逻辑,还会在 RealSubject 方法执行前后进行预处理和后置处理。
- 预处理逻辑,后置处理逻辑。
- 实现延迟加载。延迟加载可以有效地避免数据库资源的浪费,用户在访问数据库时,会立刻拿到一个代理对象,此时并没有执行任何 SQL 到数据库中查询数据,代理对象中自然也不会包含任何真正的有效数据;当用户真正需要使用数据时,会访问代理对象,此时会由代理对象去执行 SQL,完成数据库的查询。MyBatis 也提供了延迟加载功能,原理大同小异,具体的实现方式也是通过代理实现的。
会导致:代理类爆炸
Proxy
cglib
Cglib 其实就是生成了被代理类的子类
注意final修饰的不可以
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 褚成志的分享站!