Java中的代理模式

Java中的代理模式

    • 1. 静态代理
    • JDK动态代理
    • CGLib动态代理

1. 静态代理

接口

public interface ICeo {

    void meeting(String name) throws InterruptedException;
}

目标类

public class Ceo implements ICeo{

    public void meeting(String name) throws InterruptedException {
        Thread.sleep(2000);
        System.out.println("和"+name+"谈成了34亿的项目");
    }
}

代理类

public class CeoProxy implements ICeo{

    private Ceo ceo;

    public CeoProxy(Ceo ceo) {
        this.ceo = ceo;
    }

    @Override
    public void meeting(String name) throws InterruptedException {

        System.out.println("秘书登记来访: "+name);
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ceo.meeting(name);
        stopWatch.stop();
        double totalTimeMillis = stopWatch.getTotalTimeSeconds();
        System.out.println("耗时: "+totalTimeMillis);

    }
}

测试

public class CeoTest {

    public static void main(String[] args) throws InterruptedException {
        Ceo ceo = new Ceo();
        CeoProxy ceoProxy = new CeoProxy(ceo);
        ceoProxy.meeting("XXX");

    }
}

JDK动态代理

接口

public interface IDao {

    void select();
}

目标类

public class UserDao implements IDao{
    @Override
    public void select() {
        try {
            Thread.sleep(2000);
            System.out.println("select ----");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

动态代理类
在这里插入图片描述

public class JdkProxy implements InvocationHandler {

    private Object target;

    public JdkProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        StopWatch stopWatch = new StopWatch();
        System.out.println("前置方法");
        stopWatch.start();
        Object obj = method.invoke(target, args);
        stopWatch.stop();
        System.out.println("后置方法");
        System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());
        return obj;
    }
}

测试

public class DaoTest {

    public static void main(String[] args) {
        UserDao userDao = new UserDao();
        IDao dao = (IDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), UserDao.class.getInterfaces(), new JdkProxy(new UserDao()));
        dao.select();
    }
}

总结:

  1. 动态生成代理类
  2. 通过实现接口生成代理类(目标接口必须实现接口)
  3. 代理类是实现接口的方式
  4. 调用目标类使用反射调用
  5. 目标类调用本类方法只会代理一次

CGLib动态代理

在这里插入图片描述

目标类

public class ZlmDao {

    public void select(){
        try {
            Thread.sleep(2000);
            System.out.println("select ---");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

代理类

public class CglibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        System.out.println("前置增强");
        Object result = proxy.invokeSuper(obj, args);
        stopWatch.stop();
        System.out.println("后置增强");
        System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());
        return result;
    }
}

测试

public class ZlmDaoTest {
    public static void main(String[] args) {
        //实例化增强器
        Enhancer enhancer = new Enhancer();
        //设置需要代理的目标类
        enhancer.setSuperclass(ZlmDao.class);
        //设置拦截对象回调的实现类
        enhancer.setCallback(new CglibProxy());
        //生成代理类
        ZlmDao zlmDao = (ZlmDao) enhancer.create();
        zlmDao.select();
    }
}

总结

  1. 通过ASM第三方框架动态代理
  2. 无需接口(final修饰的类和方法除外)
  3. 代理类通过继承目标类的方式实现代理
  4. 调用目标类,使用子类调用父类的方式直接调用
  5. invokeSuper目标类中调用本类方法会再次代理
  6. incoke目标类中调用本来方法只会调用一次

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【信号去噪和正交采样】流水线过程的一部分,用于对L波段次级雷达中接收的信号进行降噪(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

计算机网络——应用层

文章目录 **1 网络应用模型****2 域名系统DNS****3 文件传输协议FTP****4 电子邮件****4.1 电子邮件系统的组成结构****4.2 电子邮件格式与MIME****4.3 SMTP和POP3** **5 万维网WWW****5.1 HTTP** 1 网络应用模型 客户/服务器模型 C/S 服务器服务于许多来自其他称为客户机的主…

uniapp跨域解决

uniapp跨域解决 跨域是什么 跨域指的是浏览器不能执行其他网站的脚本,当一个网页去请求另一个域名的资源时,域名、端口、协议任一不同,就会存在跨域。跨域是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。 报错…

Spring AOP 中,切点有多少种定义方式?

在 Spring AOP 中,我们最常用的切点定义方式主要是两种: 使用 execution 进行无侵入拦截。使用注解进行拦截。 这应该是是小伙伴们日常工作中使用最多的两种切点定义方式了。但是除了这两种还有没有其他的呢?今天松哥就来和大家聊一聊这个话…

【C语言初阶(20)】调试练习题

文章目录 前言实例1实例2 前言 在我们开始调试之前,应该有个明确的思路;程序是如何完成工作的、变量到达某个步骤时的值应该是什么、出现的问题大概会在什么位置。这些东西在调试之前都需要先确认下来,不然自己都不知道自己在调试个什么东西…

FFmpeg aresample_swr_opts的解析

ffmpeg option的解析 aresample_swr_opts是AVFilterGraph中的option。 static const AVOption filtergraph_options[] {{ "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,{ .i64 AVFILTER_THREAD_SLICE }, 0, INT_MA…

二十三种设计模式第二十篇--备忘录模式

备忘录模式,备忘录模式属于行为型模式。它允许在不破坏封装的情况下捕获和恢复对象的内部状态。保存一个对象的某个状态,以便在适当的时候恢复对象,该模式通过创建一个备忘录对象来保存原始对象的状态,并将其存储在一个负责管理备…

使用adb通过电脑给安卓设备安装apk文件

最近碰到要在开发板上安装软件的问题,由于是开发板上的安卓系统没有解析apk文件的工具,所以无法通过直接打开apk文件来安装软件。因此查询各种资料后发现可以使用adb工具,这样一来可以在电脑上给安卓设备安装软件。 ADB 就是连接 Android 手…

测试libcurl库的demo时,报错 curl_easy_perform() failed: SSL connect error

系统:麒麟V10 arm roothg-TR3250:/home/cur765/curl-7.65.3/docs/examples# cat /etc/os-release NAME"Kylin" VERSION"银河麒麟桌面操作系统(国防版)V10" VERSION_US"Kylin Linux Desktop (GFB)V10" IDkylin ID_LIKEdebian PRETT…

CloudDriver一款将各种网盘云盘挂在到电脑本地变成本地磁盘的工具 教程

平时我们的电脑可能由于大量的文件资料之类的导致存储空间可能不够,所以我们可以选择将网盘我们的本地磁盘用来存放东西。 CloudDrive 是一款可以将 115、阿里云盘、天翼云盘、沃家云盘、WebDAV 挂载到电脑中,成为本地硬盘的工具,支持 Window…

职工管理系统(code)

首先创建头文件、源文件&#xff0c;再编程。&#xff08;B站黑马程序员视频笔记&#xff09; 一、头文件.h 1、boss.h #pragma once #include<iostream> using namespace std; #include "worker.h"//老板类 class Boss :public Worker { public://构造函数B…

最优化方法

一. 图论 1.最小生成树 图的生成树是它的一颗含有其所有顶点的无环连通子图,一 幅加权图的最小生成树(MST)是它的一颗权值(树中的所有边的权值之和) 最小的生成树 • 适用场景&#xff1a;道路规划、通讯网络规划、管道铺设、电线布设等 题目数据 kruskal算法 稀疏图&#x…

【Git系列】了解什么是版本控制

&#x1f433;了解什么是版本控制 &#x1f9ca;1. 什么是版本控制&#x1f9ca;2. 为什么要有版本控制&#x1f9ca;3. 常见的版本控制工具&#x1f9ca;4. 版本控制分类&#x1fa9f;4.1 本地版本控制&#x1fa9f;4.2 集中版本控制&#x1fa9f;4.3 分布式版本控制 学习git之…

Elasticsearch和Kibana的安装及验证

金翅大鹏盖世英&#xff0c;展翅金鹏盖世雄。 穿云燕子锡今鸽&#xff0c;踏雪无痕花云平。 ---------------- 2023.7.31.101 ----------------- 本文密钥&#xff1a;365 Elasticsearch 是一个分布式的 RESTful 风格的搜索和数据分析引擎&#xff0c;常用来进行全文检索、…

redis 第三章

目录 1.主从复制 2.哨兵 3.集群 4.总结 1.主从复制 结果&#xff1a; 2.哨兵 3.集群 4.总结 通过集群&#xff0c;redis 解决了写操作无法负载均衡&#xff0c;以及存储能力受到单机限制的问题&#xff0c;实现了较为完善的高可用方案。

安全学习DAY09_加密逆向,特征识别

算法逆向&加密算法分类&#xff0c;特征识别 文章目录 算法逆向&加密算法分类&#xff0c;特征识别算法概念&#xff0c;分类单向散列加密 - MD5对称加密 - AES非对称加密 - RSA 常见加密算法识别特征&#xff0c;解密特点MD5密文特点BASE64编码特点AES、DES特点RSA密文…

Stable Diffusion 硬核生存指南:WebUI 中的 VAE

本篇文章聊聊 Stable Diffusion 生态中呼声最高、也是最复杂的开源模型管理图形界面 “stable-diffusion-webui” 中和 VAE 相关的事情。 写在前面 Stable Diffusion 生态中有一个很重要的项目&#xff0c;它对于 SD 生态繁荣做出的贡献可以说居功至伟&#xff0c;自去年八月…

【C++】string

string 1. 简单了解string2. string的常用接口3. 简单模拟实现string4. 写时拷贝5. 练习 1. 简单了解string string是表示字符串的字符类&#xff0c;其底层是basic_string模板类的实例化&#xff0c;只能存储单字节的字符串&#xff0c;不能操作多字节和变长字符的序列。在使…

LLM微调 | Adapter: Parameter-Efficient Transfer Learning for NLP

目的&#xff1a;大模型预训练微调范式&#xff0c;微调成本高。adapter只只微调新增的小部分参数【但adapter增加了模型层数&#xff0c;引入了额外的推理延迟。】 Adapters最初来源于CV领域的《Learning multiple visual domains with residual adapters》一文&#xff0c;其…