【JavaWeb】JDK动态代理 – 代理模式;静态代理;动态代理;JDK动态代理的实现及实现原理分析

需要掌握的程度:

  1. 什么是JDK动态代理 ?

使用jdk的反射机制,创建对象的能力(创建的是代理类的对象),而不用创建类文件,不用写java文件。

  • 动态:在程序执行时,调用jdk提供的方法才能创建代理类的对象。
  • jdk动态代理,必须有接口,目标类必须实现接口, 没有接口时,需要使用cglib动态代理。

  • 知道动态代理能做什么?

可以在不改变原来目标方法功能的前提下, 可以在代理中增强自己的功能代码。

代理模式:

1.代理:代购, 中介,换ip,商家等等。

  • 比如有一家美国的大学, 可以对全世界招生。
  • 留学中介(代理): 帮助这家美国的学校招生, 中介是学校的代理, 中介是代替学校完成招生功能。

为什么要找中介 ?

  • 中介是专业的, 方便。
  • 家长现在不能自己去找学校。 家长没有能力访问学校。 或者美国学校不接收个人来访。

买东西都是商家卖, 商家是某个商品的代理, 你个人买东西, 肯定不会让你接触到厂家的。

  1. 在开发中也会有这样的情况:

  2. a类, 本来要调用c类的方法, 完成某个功能,但是c不让a调用。

解决方案:

  • 在 a 和 c 直接 创建一个 b 代理, c 让 b访问。

a — 访问b — 访问c

3.使用代理模式的作用

  • 功能增强: 在你原有的功能上,增加了额外的功能。
  • 控制访问: 代理类不让你访问目标,例如商家不让用户访问厂家。

静态代理 :

  • 代理类是自己手动实现的,自己创建一个java类,表示代理类;同时你所要代理的目标类是确定的。

优点:实现简单;容易理解。

缺点:当你的项目中,目标类和代理类很多的时候:

1)当目标类增加了, 代理类可能也需要成倍的增加,代理类数量过多。

2)当你的接口中功能增加了, 或者修改了,会影响众多的实现类,厂家类,代理类都需要修改,影响比较多。

动态代理:

  • 在程序执行过程中,使用jdk的反射机制,创建代理类对象, 并动态的指定要代理目标类;换句话说: 动态代理是一种创建java对象的能力,让你不用创建代理类,就能创建代理类对象。

优点:

1)代理类数量可以很少。

2)当你修改了接口中的方法时,不会影响代理类。

动态代理的实现:

  • jdk 动态代理(理解):使用 java 反射包中的类和接口(InvocationHandler , Method, Proxy)实现动态代理的功能。

  • cglib动态代理(了解): cglib是第三方的工具库,cglib的原理是继承, cglib通过继承目标类,创建它的子类,在子类中重写父类中同名的方法, 实现功能的修改。

由于cglib是继承,重写方法,所以要求目标类不能是final的, 方法也不能是final的。

cglib的要求目标类比较宽松, 只要能继承就可以了。cglib在很多的框架中使用,比如 mybatis ,spring框架中都有使用。

jdk 动态代理实现步骤:

1、创建接口,定义目标类要完成的功能:

//目标接口
public interface UsbSell {
    float sell(int amount);
}

2、创建目标类实现接口:

//目标类
public class UsbKingFactory implements UsbSell {
    @Override
    //目标方法
    public float sell(int amount) {
        //厂家卖85.6元
        return 85.6f;
    }
}

3、创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//必须实现InvocationHandler接口,完成代理类要做的功能(1.调用目标方法,2.功能增强)
public class MySellHandler implements InvocationHandler {
    private Object target = null;

    //动态代理:目标对象是活动的,不是固定的,需要传入进来,传入是谁,就给谁创建代理。
    public MySellHandler(Object target) {
        //给目标对象赋值
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //储存方法执行结果
        Object res  = null;

        //执行目标方法
        res =  method.invoke(target,args);

        //商家需要加价(功能增强)
        if( res != null ){
            Float price = (Float)res;
            price = price + 25;
            res = price;
        }

        //再送你一张优惠券(功能增强)
        System.out.println("谢谢惠顾,送您一张优惠券,亲!");

        //增加的价格
        return res;
    }
}

4、使用Proxy类的静态方法,创建代理对象。 并把返回值转为接口类型:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class MainShop {
    public static void main(String[] args) {
        //1. 创建目标对象
        UsbSell factory = new UsbKingFactory();

        //2.创建InvocationHandler对象
        InvocationHandler handler = new MySellHandler(factory);

        //3.创建代理对象
        UsbSell proxy = (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),
                factory.getClass().getInterfaces(),
                handler);

        //4.通过代理执行方法
        float price = proxy.sell(1);
        System.out.println("通过动态代理对象,调用方法获得的结果:"+price);
    }
}

JDK动态代理执行流程 :

Original: https://www.cnblogs.com/Burning-youth/p/16165448.html
Author: 猿头猿脑的王狗蛋
Title: 【JavaWeb】JDK动态代理 – 代理模式;静态代理;动态代理;JDK动态代理的实现及实现原理分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/683395/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Java实现飞机大战游戏

    飞机大战详细文档 文末有源代码,以及本游戏使用的所有素材,将plane2文件复制在src文件下可以直接运行。 实现效果: 结构设计 角色设计 飞行对象类 FlyObject 战机类…

    技术杂谈 2023年7月24日
    077
  • 为什么重写equals必须重写hashCode

    equals常见面试题 为什么要重写equals 重写equals不重写hashCode会存在什么问题 总结 equals常见面试题 在开始聊之前,我们先看几个常见的面试题,看看你…

    技术杂谈 2023年7月11日
    068
  • 61.小尖尖

    dsfsf posted @2022-09-28 08:35 随遇而安== 阅读(6 ) 评论() 编辑 Original: https://www.cnblogs.com/55z…

    技术杂谈 2023年6月21日
    0110
  • 微服务组件—–SpringCloudAlibaba注册中心Nacos源码(1.4.x版本)分析

    核心功能点 【1】 服务注册:Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。Nacos …

    技术杂谈 2023年7月23日
    092
  • Prometheus Operator配置钉钉告警

    配置钉钉告警 1、注册钉钉账号->机器人管理->自定义(通过webhook接入自定义服务)->添加->复制webhook 2、创建钉钉告警插件(dingta…

    技术杂谈 2023年6月1日
    0107
  • LeetCode27.移除元素

    给你一个数组nums和一个值val,你需要 原地 移除所有数值等于val的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用O(1)额外空间并 原地 修改输入数…

    技术杂谈 2023年7月24日
    079
  • Zookeeper全解析——Paxos作为灵魂(转)

    原计划在介绍完ZK Client之后就着手ZK Server的介绍,但是发现ZK Server所包含的内容实在太多,并不是简简单单一篇Blog就能搞定的。于是决定从基础搞起比较好。…

    技术杂谈 2023年5月31日
    092
  • Spark学习(1)Spark入门

    什么事spark Spark是一种快速、通用、可扩展的大数据计算引擎.项目是用Scala进行编写,基于内存计算的 包括交互式查询和流处理 spark内置项目 Spark SQL:是…

    技术杂谈 2023年7月24日
    086
  • Linux(CentOS)安装MinIo,详细教程,附防火墙端口开放操作

    Linux安装MinIo(已配置开机重启) 1,准备安装目录和文件 系统:CentOs #进入安装目录 cd /home/minio #在线下载二进制文件 wget https:/…

    技术杂谈 2023年7月11日
    070
  • 防火墙NAT+DHCP+ACL+ACAP

    任务要求: SwitchA作为有线终端网关与DHCP Server,为无线终端与有线终端分配IP地址,并配置ACL访问控制列表控制不同用户的访问权限,客户机只能跟DMZ区域服务器互…

    技术杂谈 2023年6月21日
    0105
  • Game Engine Architecture 5

    【 Game Engine Architecture 5】 1、Memory Ordering Semantics These mysterious and vexing prob…

    技术杂谈 2023年5月31日
    065
  • vim 个性化设置

    vim 编辑器安装yum install vim vim个性化设置vim ~/.vimrc复制以下代码 set nocompatible set number set ruler …

    技术杂谈 2023年7月11日
    067
  • go 单元测试testify

    testify用go实现的一个assert风格的测试框架,这个包提供了我们需要的断言的功能,提供了非常丰富的断言方法。 提供了测试suite、断言、mock三种功能。 官方文档:h…

    技术杂谈 2023年5月31日
    081
  • 【cartographer_ros】七:主要配置参数说明

    上一节介绍了路标Landmark数据的订阅和发布,各类数据的发布和订阅基本阐述完毕。 本节会介绍cartographer的主要配置参数,研究这些参数的使用和对算法的影响。 首先还是…

    技术杂谈 2023年7月24日
    093
  • A*算法详解

    寻路算法——A*算法详解并附带实现代码 原文地址: http://www.gamedev.net/reference/articles/article2003.asp 概述 虽然掌…

    技术杂谈 2023年5月30日
    082
  • CoreProfiler/NanoProfiler性能调试监控系列总目录

    NanoProfiler – 适合生产环境的性能监控类库 之 基本功能篇 NanoProfiler – 适合生产环境的性能监控类库 之 大数据篇 NanoP…

    技术杂谈 2023年6月1日
    084
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球