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

news2024/11/15 18:26:21

文章目录

  • 代理模式
    • 代理模式的角色
    • 静态代理
      • 案例
      • 代码
        • 抽象父类接口
        • 目标对象
        • 代理对象
        • 客户端使用
        • 输出结果
    • 动态代理
      • 案例
      • 代码
        • 抽象父类与实现类
        • 代理工厂
        • 客户端
    • 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();

    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1931779.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

malloc底层实现

xv6实现的动态内存分配虽然只有不到100行代码&#xff0c;但却体现了动态内存分配的精髓&#xff0c;非常值得学习 xv6的内存布局 一谈到C语言的动态内存分配&#xff0c;就会想到堆以及malloc()和free()这两个函数。先来回顾一下XV6中的内存布局是怎样的&#xff0c;我们动态…

FPGA实训报告DAY 1(Verilog HDL)

实习日志与总结 日期&#xff1a;2024 年 7 月 10 日 星期三 姓名&#xff1a;XXX 一、实习日志 上午 9:00 - 9:30 按时到达工位&#xff0c;参加部门早会&#xff0c;了解了今天的实习任务和目标&#xff0c;即初步学习 FPGA 简介和 Verilog 基础语法知识。 9:30 - 10:30…

数据结构(5.2_1)——二叉树的基本定义和术语

二叉树的基本概念 二叉树是n(n>0)个结点的有限集合: 或者为空二叉树&#xff0c;即n0&#xff1b;或者由一个根结点和两个互不相交的被称为根的左子树和右子树组成。左子树和右子树又分别是一颗二叉树。 特点:每个结点至多只有两颗字数&#xff1b;左子树不能颠倒(二叉树…

2024牛客暑期多校第一场

H 一开始以为考后缀和&#xff0c;耽误了一会。后面直接看样例猜结论&#xff0c;数字乘位置为对答案的贡献 #include<bits/stdc.h>using namespace std;#define int long long #define PII pair<int,int>const int M1000000007;void solve() {int n;cin>>…

git 代理错误拒绝连接

git 克隆项目拒绝连接 现象 Failed to connect to 127.0.0.1 port 15732: 拒绝连接 问题描述 代理错误解决方法 取消代理 git config --global --unset http.proxy

MyBatis源码中的设计模式1

1. 建造者模式的应用 建造者模式属于创建类模式&#xff0c;通过一步一步地创建一个复杂的对象&#xff0c;能够将部件与其组装过程分开。用户只需指定复杂对象的类型&#xff0c;就可以得到该对象&#xff0c;而不需要了解其内部的具体构造细节。《Effective Java》中也提到&…

springboot的全局异常处理

主要有两个异常注解&#xff0c;RestControllerAdvice和 ExceptionHandler(Exception.class) 案例 package com.lwy.exception;import com.lwy.pojo.Result; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotati…

类和对象的简述(c++篇)

开局之前&#xff0c;先来个小插曲&#xff0c;放松一下&#xff1a; 让我们的熊二来消灭所有bug 各位&#xff0c;在这祝我们&#xff1a; 放松过后&#xff0c;开始步入正轨吧。爱学习的铁子们&#xff1a; 目录&#xff1a; 一类的定义&#xff1a; 1.简述&#xff1a; 2…

飞睿智能UWB Tag蓝牙防丢器标签,宠物安全新升级,5cm精准定位测距不迷路

宠物早已成为许多家庭不可或缺的一员&#xff0c;它们用无条件的爱温暖着我们的心房&#xff0c;陪伴我们度过每一个平凡而温馨的日子。然而&#xff0c;随着宠物活动范围的扩大和外界环境的复杂多变&#xff0c;宠物走失的风险也随之增加。每一次出门遛弯&#xff0c;都像是心…

如何使用在线工具将手机相册中的图片转换为JPG格式

我们经常在手机相册中保存大量的图片&#xff0c;无论是家庭聚会的照片还是旅行的瞬间&#xff0c;每一幅图像都承载着珍贵的记忆。然而&#xff0c;有时候我们会遇到图片格式不兼容的问题&#xff0c;尤其是在需要将图片分享到特定平台或编辑时。 例如&#xff0c;某些社交平台…

PCIe EtherCAT实时运动控制卡PCIE464的IO与编码器读写应用

硬件介绍 PCIE464运动控制卡是正运动推出的一款EtherCAT总线脉冲型、PCIE接口式的运动控制卡&#xff0c;可选6-64轴运动控制&#xff0c;支持多路高速数字输入输出&#xff0c;可轻松实现多轴同步控制和高速数据传输。 PCIE464运动控制卡适合于多轴点位运动、插补运动、轨迹规…

Qt 多语言

记录Qt多语言的实现过程 目录 1.项目配置文件.pro配置 2.程序中的字符串用tr()封装 3.生成翻译文件 4.使用Qt语言家修改翻译文件 4.1使用Qt语言家打开 4.2 .更改文件配置 5. 生成qm文件 6.代码执行切换语言 6.1入口处 6.2 事件执行 0.效果 1.项目配置文件.pro配置 T…

观测云对接 Fluentd 采集业务日志最佳实践

概述 Fluentd 是一个开源数据收集器&#xff0c;专为简化日志管理和使日志数据更加易于访问、使用而设计。作为一个高度可扩展的工具&#xff0c;它能够统一数据收集和消费过程&#xff0c;使得构建实时分析的日志系统变得更加高效。 观测云目前已集成 Fluentd &#xff0c;可…

十、Java集合 ★ ✔(模块18-20)【泛型、通配符、List、Set、TreeSet、自然排序和比较器排序、Collections、可变参数、Map】

day05 泛型,数据结构,List,Set 今日目标 泛型使用 数据结构 List Set 1 泛型 1.1 泛型的介绍 ★ 泛型是一种类型参数&#xff0c;专门用来保存类型用的 最早接触泛型是在ArrayList&#xff0c;这个E就是所谓的泛型了。使用ArrayList时&#xff0c;只要给E指定某一个类型…

mybatisPlus和mybatis的版本冲突问题、若依换成MP、解决git无法推送、使用若依框架的swagger、以后再遇到团队项目应该怎么做。

20240716 一. mybatisPlus和mybatis的版本冲突问题1. 使用前的准备2. 我遇到了一个很严重的问题。3. 解决问题&#xff0c;好吧也没解决&#xff0c;发现问题&#xff01;&#xff01; 二、该死的git&#xff01;&#xff01;&#xff01;&#xff01;1. 解决无法在idea中使用g…

2024年公路水运工程施工企业安全生产管理人员证模拟考试题库及公路水运工程施工企业安全生产管理人员理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年公路水运工程施工企业安全生产管理人员证模拟考试题库及公路水运工程施工企业安全生产管理人员理论考试试题是由安全生产模拟考试一点通提供&#xff0c;公路水运工程施工企业安全生产管理人员证模拟考试题库是…

大数据平台之YARN

Hadoop YARN&#xff08;Yet Another Resource Negotiator&#xff09;是Hadoop 2.x引入的一个通用资源管理和作业调度框架&#xff0c;它将资源管理和作业调度/监控分离开来&#xff0c;从而提升了集群的资源利用率和可扩展性。YARN是Hadoop生态系统的核心组件之一&#xff0c…

Go 1.19.4 函数-Day 08

1. 函数概念和调用原理 1.1 基本介绍 函数是基本的代码块&#xff0c;用于执行一个任务。 Go 语言最少有个 main() 函数。 你可以通过函数来划分不同功能&#xff0c;逻辑上每个函数执行的是指定的任务。 函数声明告诉了编译器函数的名称&#xff0c;返回类型&#xff0c;和参…

持续集成06--Jenkins构建触发器

前言 在持续集成&#xff08;CI&#xff09;的实践中&#xff0c;构建触发器是自动化流程中不可或缺的一环。它决定了何时启动构建过程&#xff0c;从而确保代码变更能够及时地得到验证和反馈。Jenkins&#xff0c;作为业界领先的CI/CD工具&#xff0c;提供了多种构建触发器选项…

【C++编程】双端数组 deque 容器基本操作

&#x1f525; 特点&#xff1a;deque 头插、头删速度比 vector 快 deque 是一个双向队列&#xff08;double-ended queue&#xff09;&#xff0c;可以在队列的两端进行元素的插入和删除操作。 deque 涵盖了 queue&#xff08;队列&#xff09;、stack&#xff08;堆栈&#x…