Java - 代理模式

1. 什么是代理设计模式

首先要明白Java的23种设计模式,是编写了很多代码后总结出来的经验,根据业务使用设计模式能提高程序的扩展性、减少代码量等等。

代理设计模式就是为了在不侵入原代码的前提下进行功能增强

例如: 想在某个方法刚开始执行时打印一下日志,但是又不好将打印日志逻辑直接写入原来的方法里。这时就可以创建一个代理类,代理类具有和原始类相同的方法,通过让代理类持有真实对象,然后代码调用的时候直接调用代理类的方法,来达到增强业务逻辑的目的。

service层代码包括核心业务代码和附加代码,附加代码可有可无,因此在这使用代理设计模式,将核心业务和附加功能分开。
在这里插入图片描述

2. 静态代理设计模式

静态代理就是程序员手动定义代理类,在程序运行时代理类的.class文件已经有了。

缺点:

如果需要定义多个代理类,都手写那不是累死了!也会造成类的数量爆炸,有一个原始类就要有一个代理类。

Java代码实现

  1. 包结构
    在这里插入图片描述
  2. 委托类
    在这里插入图片描述
  3. 代理类
    在这里插入图片描述
  4. 测试在这里插入图片描述

3. 动态代理设计模式

动态代理就是让程序自动生成代理类,不需要我们自己定义代理类了。代理类的定义是在程序运行时动态生成。

Java 代码 实现

  1. 定义方法拦截器,编写增强逻辑
    在这里插入图片描述
  2. 测试
    在这里插入图片描述

4. 动态代理的两种实现

  1. JDK动态代理:使用JDK提供的工具类实现。

  2. CGLIB动态代理:使用CGLIB外部包实现。

两者区别:

JDK动态代理 委托类必须要实现接口。

CGLIB动态代理 委托类不需要有实现接口,委托类和代理类是父子类的关系。

CGLIB实现步骤:

  1. 引入依赖坐标

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
    </dependency>
    
  2. 有一个委托类(业务类)

    package proxy_dynamic;
    
    /**
     * @Date: 2022/4/24 19:52
     * @author: ZHX
     * @Description: 委托类
     */
    public class Consignor {
        public void buy() {
            System.out.println("委托类:买房、签合同、交钱");
        }
    
        public void call() {
        }
    }
    
    
  3. 获取代理对象测试

    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;
        }
    }
    

总结:

  1. 使用代理技术就是为了在不入侵原有代码的情况下增强业务逻辑。
  2. 静态代理太过于繁琐。
  3. 有接口就用JDK动态代理,没有接口就用CGLIB动态代理。
  4. JDK动态代理,按照接口结构创建代理类,能用于多态替换。
  5. CGLIB动态代理,按照委托类结构创建代理类。
  6. CGLIB 也提供了按照接口生成代理类的方法。

5. 参考资料

https://www.bilibili.com/video/BV185411477k?p=63&vd_source=c581024b8cd9585ec6a75c56ac05571a

JDK动态代理为什么必须要基于接口?

B站黑马程序员

静态代理和动态代理的区别,什么场景使用

百度百科

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值