1. 什么是代理设计模式
首先要明白Java的23种设计模式,是编写了很多代码后总结出来的经验,根据业务使用设计模式能提高程序的扩展性、减少代码量等等。
代理设计模式就是为了在不侵入原代码的前提下进行功能增强
例如: 想在某个方法刚开始执行时打印一下日志,但是又不好将打印日志逻辑直接写入原来的方法里。这时就可以创建一个代理类,代理类具有和原始类相同的方法,通过让代理类持有真实对象,然后代码调用的时候直接调用代理类的方法,来达到增强业务逻辑的目的。
service层代码包括核心业务代码和附加代码,附加代码可有可无,因此在这使用代理设计模式,将核心业务和附加功能分开。
2. 静态代理设计模式
静态代理就是程序员手动定义代理类,在程序运行时代理类的.class文件已经有了。
缺点:
如果需要定义多个代理类,都手写那不是累死了!也会造成类的数量爆炸,有一个原始类就要有一个代理类。
Java代码实现
- 包结构
- 委托类
- 代理类
- 测试
3. 动态代理设计模式
动态代理就是让程序自动生成代理类,不需要我们自己定义代理类了。代理类的定义是在程序运行时动态生成。
Java 代码 实现
- 定义方法拦截器,编写增强逻辑
- 测试
4. 动态代理的两种实现
-
JDK动态代理:使用JDK提供的工具类实现。
-
CGLIB动态代理:使用CGLIB外部包实现。
两者区别:
JDK动态代理 委托类必须要实现接口。
CGLIB动态代理 委托类不需要有实现接口,委托类和代理类是父子类的关系。
CGLIB实现步骤:
-
引入依赖坐标
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>
-
有一个委托类(业务类)
package proxy_dynamic; /** * @Date: 2022/4/24 19:52 * @author: ZHX * @Description: 委托类 */ public class Consignor { public void buy() { System.out.println("委托类:买房、签合同、交钱"); } public void call() { } }
-
获取代理对象测试
public class Test { public static void main(String[] args) { //使用CGLIB动态代理 Consignor consignor = new Consignor(); Consignor o1 = (Consignor) Enhancer.create(Consignor.class, new MyMethodInterceptor(consignor)); o1.buy(); } } class MyMethodInterceptor implements MethodInterceptor { Object origin; public MyMethodInterceptor(Object origin) { this.origin = origin; } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { Object result = null; System.out.println("日志开始........................"); result = method.invoke(origin, objects); System.out.println("日志结束........................"); return result; } }
总结:
- 使用代理技术就是为了在不入侵原有代码的情况下增强业务逻辑。
- 静态代理太过于繁琐。
- 有接口就用JDK动态代理,没有接口就用CGLIB动态代理。
- JDK动态代理,按照接口结构创建代理类,能用于多态替换。
- CGLIB动态代理,按照委托类结构创建代理类。
- CGLIB 也提供了按照接口生成代理类的方法。
5. 参考资料
https://www.bilibili.com/video/BV185411477k?p=63&vd_source=c581024b8cd9585ec6a75c56ac05571a