• 代理模式(静态代理,动态代理,cglib代理)


    代理模式

    代理模式属于结构型的模式,通过代理对象来访问目标对象,即可以扩展目标对象的功能,比如日志记录,或者是安全检查,我们常用的AOP面向切面编程是属于一种代理模式。

    代理模式的形式:静态代理,动态代理(JDK 代理),cglib代理(基于内存实现)

    代理模式的角色

    • 客户端:通过代理对象访问目标对象
    • 代理对象
    • 目标对象

    代理模式.drawio

    静态代理

    代理对象与目标对象都要实现同一个接口或者父类,客户端通过代理对象来访问目标对象

    案例

    静态代理.drawio

    代码

    抽象父类接口
    
    
    /**
     *  抽象父类接口
     *
     * @author: Hui
     **/
    public interface ITeacher {
    
        public void teach();
    
    }
    
    
    目标对象
    /**
     *  目标对象
     *
     * @author: Hui
     **/
    public class TeacherTarget implements ITeacher{
        @Override
        public void teach() {
            System.out.println(" 老师开始授课了 ~~~~");
        }
    }
    
    代理对象
    /**
     *  代理对象
     *
     * @author: Hui
     **/
    public class TeacherProxy implements ITeacher{
    
        private ITeacher iteacher;
    
        public TeacherProxy(ITeacher teacher) {
            this.iteacher = teacher;
        }
    
        @Override
        public void teach() {
            System.out.println("代理对象  开始");
            iteacher.teach();
            System.out.println("代理对象  结束");
        }
    }
    
    
    客户端使用
    /**
     * 客户端
     *
     * @author: Hui
     **/
    public class Client {
    
        public static void main(String[] args) {
    
            TeacherTarget teacherTarget = new TeacherTarget();
    
            TeacherProxy teacherProxy = new TeacherProxy(teacherTarget);
    
            teacherProxy.teach();
        }
    }
    
    
    输出结果

    image-20240709143855244

    动态代理

    又称为 JDK 代理,通过JDK 反射的包来实现。

    案例

    动态代理.drawio

    代码

    抽象父类与实现类
    
    /**
     * 抽象父类
     *
     */
    public interface ITeacher {
    
        void teach();
    }
    
    /**
     *  目标对象
     *
     * @author: Hui
     **/
    public class TeacherDao implements ITeacher{
        @Override
        public void teach() {
            System.out.println("老师授课中 ~~~~");
        }
    }
    
    代理工厂
    /**
     *  代理工厂
     *
     * @author: Hui
     **/
    public class ProxyFactory {
    
        private Object target;
    
        //构造器
        public ProxyFactory(Object target){
            this.target = target;
        }
    
        //获取代理对象
        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("开始代理");
                    Object resultVal = method.invoke(target, args);
                    System.out.println("结束代理");
                    return resultVal;
                }
            });
        }
    }
    
    客户端
    /**
     *  客户端
     *
     * @author: Hui
     **/
    public class Client {
    
        public static void main(String[] args) {
    
            ITeacher teacherDao = new TeacherDao();
            // 创建代理对象
            ITeacher proxyFactory = (ITeacher) new ProxyFactory(teacherDao).getProxyInstance();
    
            proxyFactory.teach();
        }
    }
    

    cglib代理

    cglib代理是可以不急于抽象父类或者抽象接口。

    使用的代理工厂实现methodIntecetor,重写 intecetor方法就可以了。

    引入依赖

           <!-- https://mvnrepository.com/artifact/cglib/cglib -->
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.2.5</version>
            </dependency>
    

    目标对象

    /**
     *  目标对象
     *
     * @author: Hui
     **/
    public class TeacherTarget {
    
        public void teach()
        {
            System.out.println("老师授课中...");
        }
    
    }
    

    代理工厂

    /**
     *  代理工厂
     *
     * @author: Hui
     **/
    public class ProxyFactory implements MethodInterceptor {
    
        private Object target;
    
        public Object getProxyInstance(Object obj){
            this.target = obj;
            //1.创建工具类
            Enhancer enhancer = new Enhancer();
            //2.设置父类
            enhancer.setSuperclass(obj.getClass());
            //3.设置回调函数
            enhancer.setCallback(this);
            //4.创建子类对象,即代理对象
            Object proxyObj = enhancer.create();
            //返回代理对象
            return proxyObj;
        }
    
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("cglib代理开始");
            Object resultVal = method.invoke(target, objects);
            System.out.println("cglib代理结束");
            return resultVal;
        }
    }
    

    客户端

    /**
     *  客户端
     *
     * @author: Hui
     **/
    public class Client {
        public static void main(String[] args) {
    
            ProxyFactory proxyFactory = new ProxyFactory();
    
            TeacherTarget teacherProxy =(TeacherTarget) proxyFactory.getProxyInstance(new TeacherTarget());
    
            teacherProxy.teach();
    
        }
    }
    
  • 相关阅读:
    Python学习—基础
    【LIUNX】查询IP与MAC地址
    Ray Tracing Gems II
    Java 零矩阵
    python中深拷贝和浅拷贝的区别
    拒绝服务攻击工具
    Redis的持久化策略:RDB与AOF(面试题详解)
    shopee买家通系统一款全自动化操作的软件
    Chrome开发自定义右键菜单实现快速跳转到指定页面
    前端开发引入element plus与windi css
  • 原文地址:https://blog.csdn.net/m0_64372868/article/details/140375179