1.为什么说JDK动态代理必须要实现当前父接口才能使用

  JDK动态代理是基于接口的代理,它要求目标类(被代理的类)必须实现一个或多个接口。这是因为JDK动态代理是通过创建目标类的接口的代理对象来实现的,代理对象实现了目标接口,并在方法调用时委托给InvocationHandler中的invoke方法来处理。

  在JDK动态代理中,Proxy类的newProxyInstance方法接受一个ClassLoader,一组接口和一个InvocationHandler,然后生成一个代理类的实例。这个代理类实例实现了指定的接口,并将方法调用委托给InvocationHandler中的invoke方法。

  自我结论:可能是因为比如生成的$Proxy代理类如果没有父接口 那他内部也不知道通过InvocationHandler来调用谁来进行增强了 还有就是可能有一些决策问题。

2.JDK动态代理的$Proxy实现

  Cat父接口

//父接口
interface Cat {
//开车
void drive();
//下车
void off();
}
  InvocationHandler接口
interface InvocationHandler {
//代理类,代理方法,代理方法参数
Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}
  $Proxy0代理类
class $Proxy0 implements Cat {
private InvocationHandler invocationHandler;
private Map<String, Method> methods; public $Proxy0(InvocationHandler invocationHandler) {
this.invocationHandler = invocationHandler;
this.methods = new HashMap<>();
try {
methods.put("drive", Cat.class.getMethod("drive"));
methods.put("off", Cat.class.getMethod("off"));
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
} @Override
public void drive() {
try {
invocationHandler.invoke(this, methods.get("drive"), new Object[0]);
} catch (Throwable e) {
throw new RuntimeException(e);
}
} @Override
public void off() {
try {
invocationHandler.invoke(this, methods.get("off"), new Object[0]);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
  CustomLogicHandler 多个方法不同增强
class CustomLogicHandler implements InvocationHandler {
private Object target;
private Map<String, Runnable> methodEnhancements; public CustomLogicHandler(Object target) {
this.target = target;
this.methodEnhancements = new HashMap<>();
methodEnhancements.put("drive", () -> System.out.println("开车增强"));
methodEnhancements.put("off", () -> System.out.println("下车增强"));
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 根据方法名获取增强逻辑
Runnable enhancement = methodEnhancements.get(method.getName());
if (enhancement != null) {
enhancement.run();
}
// 委托给目标对象执行原方法
Object result = method.invoke(target, args);
return result;
}
}

  Fute实现类(待增强类)

class FuTe implements Cat {
@Override
public void drive() {
System.out.println("我要开始开车了");
} @Override
public void off() {
System.out.println("我要下车了");
}
public static void main(String[] args) {
Cat realObject = new FuTe();
CustomLogicHandler customLogicHandler = new CustomLogicHandler(realObject); Cat proxyObject = (Cat) new $Proxy0(customLogicHandler); proxyObject.drive();
System.out.println("------");
proxyObject.off();
}
}

  总结:在这个例子中,CustomLogicHandler中的methodEnhancements存储了不同方法的增强逻辑,而不再使用if语句。在$Proxy0中的methods也类似地存储了不同方法的Method对象。这种方式可以更灵活地处理不同方法的增强逻辑,而不需要使用大量的if语句。

通过JDK动态代理类实现一个类中多种方法的不同增强的更多相关文章

  1. SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架

    1 JDK动态代理详解 静态代理.JDK动态代理.Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文. 1.1 JDK代理的基本步骤 >通过实现InvocationHandler接口来 ...

  2. Java基础-JDK动态代理

    JDK的动态代理依靠接口实现  代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...

  3. 【原创】JDK动态代理,此次之后,永生难忘。

    动态代理,这个词在Java的世界里面经常被提起,尤其是对于部分(这里强调“部分”二字,因为有做了一两年就成大神的,实力强的令人发指,这类人无疑是非常懂动态代理这点小伎俩的)做了一两年新人来说,总是摸不 ...

  4. Spring AOP高级——源码实现(3)AopProxy代理对象之JDK动态代理的创建过程

    spring-aop-4.3.7.RELEASE  在<Spring AOP高级——源码实现(1)动态代理技术>中介绍了两种动态代理技术,当然在Spring AOP中代理对象的生成也是运用 ...

  5. 有点深度的聊聊JDK动态代理

    在接触SpringAOP的时候,大家一定会被这神奇的功能所折服,想知道其中的奥秘,底层到底是如何实现的.于是,大家会通过搜索引擎,知道了一个陌生的名词:动态代理,慢慢的又知道了动态代理有多种实现方式, ...

  6. JDK动态代理浅析

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2018-06-29/17.html 作者:夜月归途 出处:http://www.guitu ...

  7. jdk 动态代理的原理

    一.代理设计模式 代理设计模式是Java常用的设计模式之一. 特点: 01.委托类和代理类有共同的接口或者父类: 02.代理类负责为委托类处理消息,并将消息转发给委托类: 03.委托类和代理类对象通常 ...

  8. (转)细说JDK动态代理的实现原理

    原文:http://blog.csdn.net/mhmyqn/article/details/48474815 关于JDK的动态代理,最为人熟知的可能要数Spring AOP的实现,默认情况下,Spr ...

  9. JDK动态代理代码示例

    JDK动态代理代码示例 业务接口 实现了业务接口的业务类 实现了InvocationHandler接口的handler代理类 1.业务接口 package com.wzq.demo01; /** * ...

  10. jdk动态代理使用及原理

    jdk动态代理的使用 1.创建实现InvocationHandler接口的类,实现invoke(Object proxy, Method method, Object[] args)接口,其中invo ...

随机推荐

  1. Go语言系列——11-数组和切片、12-可变参数函数、13-Maps、14-字符串、15-指针、16-结构体、17-方法、18-接口(一)、19-接口(二)、19-自定义集合类型、20-并发入门

    文章目录 11-数组和切片 数组 数组的声明 数组是值类型 数组的长度 使用 range 迭代数组 多维数组 切片 创建一个切片 切片的修改 切片的长度和容量 使用 make 创建一个切片 追加切片元 ...

  2. Python基础——计算机组成原理、操作系统概述、编程语言的由来、编程语言分类、python介绍、 安装Cpython解释器、 第一个python程序

    文章目录 一 引子: 1.1 什么是语言?什么是编程语言?为何要有编程语言? 1.2 什么是编程?为什么要编程? 二 计算机组成原理 2.1.什么是计算机? 2.2.为什么要用计算机? 2.3.计算机 ...

  3. 报Bug的礼仪

    不要对1个程序员说:你的代码有Bug.他的第1反应是:1.你的环境有问题吧:2.傻逼你会用吗? 如果你委婉的说:你这个程序和预期的有点不1致,你看看是不是我的打开姿势有问题?他本能的会想:擦,是不是出 ...

  4. scnhealthcheck

    在CPU补丁中,Oracle提供了一个脚本 scnhealthcheck.sql 用于检查数据库当前SCN的剩余情况.该脚本的算法和以上描述相同,最终将最大合理SCN 减去当前数据库SCN,计算得出一 ...

  5. [ABC202E] Count Descendants 题解

    Count Descendants 题目大意 给定一颗以 \(1\) 为根的树,多次询问求某点的子树中深度为给定值的点的个数. 思路分析 对于每个深度开一个 vector,从大到小存下这个深度的所有点 ...

  6. 创建vue项目并搭建JSONSERVER

    1.该前提是你已经搭建好vue-cli脚手架,开始创建一个新项目,输入 vue init webpack demo(demo是自定义项目名). 2.cd demo 进入项目安装依赖 3.在已经创建的项 ...

  7. GPL协议原文及中文翻译

    GPL协议原文及中文翻译 原文参考链接 翻译参考链接 原文 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 19 ...

  8. Macos下用Clion调试chromium源码

    1:下载CLion 2021.1.3(网上有破解版) 2:选择File->Open 导入chromium源码 3:在Src同级目录新建一个CMakeLists.txt 4:点击clion编译按钮 ...

  9. 🎁平平无奇的 Docker 命令(日常流)

    Docker search docker search 命令用于在 Docker Hub 上搜索镜像,语法如下: docker search [OPTIONS] TERM 常用的选项包括: --fil ...

  10. k8s-1.23.6 安装部署文档(超详细)

    一.文档简介 作者:lanjiaxuan 邮箱:lanheader@163.com 博客地址:https://www.cnblogs.com/lanheader/ 更新时间:2022-09-09 二. ...