• 设计模式——代理模式


    静态代理

    例子:有一个教师类,教师类有一个教书方法
    需要使用一个代理类来代理教师,将教师类聚合到代理类里面
    在这里插入图片描述
    具体代码如下:
    首先创建一个接口,不仅教师类需要实现,代理类也需要实现,但是注意的是,代理类实现的时候,是使用的教师类的教书方法。

    package com.StaticProxy;
    
    //代理模式
    public interface ITeacherDao {
        void teach();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    package com.StaticProxy;
    
    //真正的实体对象,需要被代理的类
    //该类中有真正的教书方法
    public class TeacherDao implements ITeacherDao {
    
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void teach() {
            System.out.println(this.name + "在教书");
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    package com.StaticProxy;
    
    //代理,需要代理TeacherDao,它虽然有teach方法,但是不是真的会教书,所以需要调用TeacherDao的教书方法
    public class TeacherDaoProxy implements ITeacherDao{
        private ITeacherDao teacherDao;
    
        public TeacherDaoProxy(ITeacherDao teacherDao) {
            this.teacherDao = teacherDao;
        }
    
        @Override
        public void teach() {
            System.out.println("通过代理对象。。。");
            System.out.println("代理使用真实的teacherDao在教书");
            teacherDao.teach();
            System.out.println("代理结束");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    使用代理类:

    package com.StaticProxy;
    
    public class Client {
        public static void main(String[] args) {
            //新建一个TeacherDAO类
            TeacherDao teacherDao = new TeacherDao();
            teacherDao.setName("lisi");
    
            //使用一个代理类来代理教师类
            TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
            teacherDaoProxy.teach();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    因为是静态代理,所以就是教师代理类,要是换一个需要代理的类,就不能实现了。一次引入动态代理

    动态代理

    使用一个proxyFactory,传入一个Target目标对象,动态生成对应的目标代理对象

    在这里插入图片描述
    首先需要一个目标对象类的接口。

    package com.DynamicProxy;
    
    public interface ITeacherDao {
        void teach();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    目标对象类实现这个接口。

    package com.DynamicProxy;
    
    public class TeacherDao implements ITeacherDao{
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void teach() {
            System.out.println(this.name + "在教书");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    动态代理工厂
    在该类中,使用Proxy.newProxyInstance,生成代理对象,这个方法有3个参数:

    1. ClassLoader loader :当前目标对象使用的类加载器,获取加载器的方法固定
    2. Class[] interfaces:目标对象实现的接口类型,使用泛型方法确定类型
    3. InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器方法,会把当前执行的目标对象方法作为一个参数传入
    package com.DynamicProxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyFactory {
    
        //维护一个目标对象,object  这里相当于TeacherDao了
        private Object target;
    
        //构造器,对target进行初始化
        public ProxyFactory(Object target){
            this.target = target;
        }
    
        //给目标对象 生成一个代理对象
    
    //    ClassLoader loader :当前目标对象使用的类加载器,获取加载器的方法固定
    //    Class[] interfaces:目标对象实现的接口类型,使用泛型方法确定类型
    //    InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器方法,会把当前执行的目标对象方法作为一个参数传入
        public Object getProxyInstance(){
    
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("jdk代理开始---");
                            //反射机制调用目标对象的方法
                            Object returnVal = method.invoke(target, args);
                            return returnVal;
                        }
                    });
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    package com.DynamicProxy;
    
    import com.DynamicProxy.TeacherDao;
    
    public class Client {
        public static void main(String[] args) {
            //目标对象
    //        ITeacherDao teacherDao = new TeacherDao();
            TeacherDao teacherDao = new TeacherDao();
            teacherDao.setName("lisi");
    
            //使用代理工厂 给目标对象创建代理对象
            ProxyFactory proxyFactory = new ProxyFactory(teacherDao);
            //强转成ITeacherDao类型 否则没办法调用教书方法
            ITeacherDao proxyInstance =(ITeacherDao) proxyFactory.getProxyInstance();
            //proxyInstance : class com.sun.proxy.$Proxy0 内存中动态生成了代理对象
            proxyInstance.teach();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    【JVM】垃圾回收机制详解(GC)
    产品新闻稿撰写流程是怎样的,纯干货
    项目:【Boost搜索引擎】
    Java程序员薪资大比拼,网友:竟然达标了?
    git分支应用和多人协作
    uniapp iosApp H5+本地文件操作(写入修改删除等)
    2月26日做题总结(C/C++真题)
    找出字符串中第一个匹配项的下标
    【改进灰狼优化算法】基于协调探索和开发能力的改进灰狼优化算法求解单目标优化问题(Matlab代码实现)
    Yolov8小目标检测(23):多分支卷积模块RFB,扩大感受野提升小目标检测精度
  • 原文地址:https://blog.csdn.net/weixin_45332508/article/details/137867132