代理模式总结

代理模式总结

一 . 什么是代理模式?

​ 举一个生活中的案列, 一个人想要解决法律纠纷, 但是他并不懂法律,所以他就可以选择去请律师,律师就负责去完成这个人不能完成的事情,这个人只负责提供一些基本的证据及线索等等。这就是一个典型的代理, 这就完成了业务的增强,这也是代理存在的意义。

  • 应用场景:用于对原生函数——法律诉讼,的增加与扩展。
  • 工作模块:分为被代 理对象——要提出法律诉讼的这个人,与代理对象——律师。
二 . java中的代理分类

整体可以分为静态代理和动态代理

1. 静态代理

​ 静态代理主要是在编写代码时由我们手动编写代理类去实现拓展的功能,之所以称之为静态,是因为所有的代理关系全部都是固定死的。就像上面的场景中,他们的关系是1对1固定的。

2.动态代理

​ 动态代理相对于静态代理,最大的变化就是不用手动去实现自己的代理类了,只需要通过JDK或者CGLIB去获得一个代理类,而代理类是在运行时被生成与加载的。动态代理就是将我们手动编写代理实现这一过程变成了由框架自己去完成,然后再自己加载运行。框架是如何完成的呢?我们知道代码都会成为.java文件,然后编译成.class文件,最终加载进JVM成为一个类。框架就是在运行时,帮我们生成代理类对应的java/class文件,然后再加载进JVM成为一个类,最终反射创建对应的代理对象返回给我们去使用。

三.实现

代理实现的前提是如何能够获取到原接口的调用。因此就可以有两种方式:组合与继承。

  • 组合:与被代理类实现相同的接口,然后向代理类传入被代理类的引用,从而调用到目标函数。
  • 继承:继承被代理类,重写目标函数,然后通过super调用到目标函数。
    在这里插入图片描述

1.静态代理–组合(实现相同接口)

​ 1) 定义了一个所有老师的一个接口

public interface AllTeacher {
    public void teach();
}

​ 2) 一个具体的老师实现了这个接口,重写了teach方法

public class MusicTeacher  implements  AllTeacher{
    @Override
    public void teach() {
        System.out.println("教音乐");
    }
}

  1. 代理对象也实现了这个接口,并包含这个MusicTeacher类对象,对musicTeacher的功能做了进一步增强。
public class TeacherProxy implements  AllTeacher {
    MusicTeacher musicTeacher;
    public TeacherProxy(MusicTeacher musicTeacher){
        this.musicTeacher = musicTeacher;
    }

    @Override
    public void teach() {
        System.out.println("代理开始。。。");
        System.out.println("教语文");
        musicTeacher.teach();
        System.out.println("代理结束");

    }
}

2.静态代理–继承

增加了MusicTeacher的子类,调用super.teach()。

public class TeacherProxy  extends MusicTeacher{
    
    @Override
    public void teach() {
        System.out.println("代理开始。。。");
        System.out.println("教语文");
        super.teach();
        System.out.println("代理结束");
    }
}

3.动态代理 — JDK代理模式

public class JDKProxy {
    public static void main(String[] args) {
        MusicTeacher musicTeacher = new MusicTeacher();//被代理对象

        AllTeacher proxyteacher = (AllTeacher) proxy(musicTeacher);
        proxyteacher.teach();
    }

    public static <T> T proxy(T t){

       T ret = (T) Proxy.newProxyInstance(t.getClass().getClassLoader(),//类加载器
                t.getClass().getInterfaces(),
               new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//重写方法

                        System.out.println("开始代理。。。");
                        System.out.println("教语文");
                        Object ret = method.invoke(t,args);
                        System.out.println("代理结束");
                        return ret;
                    }
                });
        return ret;
    }

}

4 . 动态代理 --CGLIB代理模式

核心就是拦截父类的所有函数,然后通过调用子类的方法去实现增强。

public class CGLIBProxy {
    public static void main(String[] args) {
        MusicTeacher musicTeacher = new MusicTeacher();//被代理对象

        MusicTeacher proxyteacher = (MusicTeacher) proxy(musicTeacher);
        proxyteacher.teach();
    }

    public static <T> T proxy(T t){
        Enhancer enhancer =  new Enhancer();
        enhancer.setSuperclass(t.getClass());// 创建传入的类的子类
        // 完成创建后 回调自己
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {//重写方法
                System.out.println("开始代理。。。");
                System.out.println("教语文");
                Object ret = methodProxy.invoke(t,objects);
                System.out.println("代理结束");
                return ret;
            }
        });
        return (T) enhancer.create();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值