返回顶部
首页 > 资讯 > 后端开发 > Python >JDK动态代理,代理接口没有实现类,实现动态代理方式
  • 288
分享到

JDK动态代理,代理接口没有实现类,实现动态代理方式

2024-04-02 19:04:59 288人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录jdk动态代理,代理接口没有实现类,实现动态代理被代理的接口:代理对象:那么接下来测试一下:jdk动态代理为什么要接口先通过一个简单例子实现功能:编写测试方法:里面的getPro

JDK动态代理,代理接口没有实现类,实现动态代理

JDK代理,代理的是接口,那么笔者想一想,既然代理的是接口,那如果没有实现类怎么办,能不能代理。答案是可以的,mybatis就是这样的。

Mybatis使用JDK动态代理来实现Mapper接口,事先保存好Mapper接口,和接口声明的方法,返回值,参数类型,然后代理类的方法调用的时候使用MapperMethod这个事先放入方法缓存里的对象来真实调用功能。

笔者极度简化了一下代码:

被代理的接口:


public interface Subject2 { 
    String selectById();
}

这个接口可以看成是Mapper接口

代理对象:


public class SubjectProxy2<T> implements InvocationHandler { 
    private Class<T> proxyInterface;
    //这里可以维护一个缓存,存这个接口的方法抽象的对象     
    SubjectProxy2(Class<T> proxyInterface){
        this.proxyInterface = proxyInterface;
    } 
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("selectById")){
            //String result = (String) method.invoke(proxyInterface,args);
            //这里可以得到方法抽象对象来调用真的的查询方法
            System.out.println("selectById调用成功");
        }
        return null;
    } 
    public T getProxy(){
        return (T) Proxy.newProxyInstance(proxyInterface.getClassLoader(),new Class[]{proxyInterface},this);
    }
}

这个代理类使用了泛型,说明这个代理类可以代理所有的mapper接口。

那么接下来测试一下:


public class ProxyTest2 { 
    public static void main(String[] args) {
        SubjectProxy2<Subject2> subjectProxy2 = new SubjectProxy2(Subject2.class);
        Subject2 subject2 = subjectProxy2.getProxy();
        subject2.selectById();
    }
}

结果不言而喻。肯定会有相应的输出

没有看mybatis源码的时候,我以为动态代理一定要要有实现类才能代理,但是看了优秀的顶级大牛的源码之后,我才发现,原来还可以这样。

jdk动态代理为什么要接口

jdk的动态代理为什么用接口,内部是什么原理呢?看了几篇文章貌似都没讲的清楚明白,因此来解释一下。

先通过一个简单例子实现功能:


//接口
public interface SayService { 
 void say(String name);
}
//实现类
public class SayServiceImpl implements SayService{ 
 @Override
 public void say(String name) {
  System.out.println(name);
 }
}

然后再自定义一个增强类, 实现InvocationHandler接口:


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; 
public class WavingInvocationHandler  implements InvocationHandler{ 
 private Object target; 
 public void setTarget(Object target) {
  this.target = target;
 }
 
 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  System.out.println("方法执行之前!");
  Object obj = method.invoke(target, args);
  System.out.println("方法执行之后!");
  return obj;
 }
}

编写测试方法:


import sun.misc.ProxyGenerator; 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Proxy;
 
public class Test { 
 public static void main(String[] args) { 
  //接口
  SayService sayService = new SayServiceImpl();
  //织入类
  WavingInvocationHandler handler = new WavingInvocationHandler();
  handler.setTarget(sayService);
  //代理类--增强的对象
  SayService s = (SayService) Proxy.newProxyInstance(
    sayService.getClass().getClassLoader(),
    sayService.getClass().getInterfaces(), handler);
 
  s.say("say()");//执行代理对象完成业务
  
 
  //将jdk中生成代理类输出到本地.Class文件,之后可以通过反编译软件打开查看
  createProxyClassFile("test12345",sayService.getClass().getInterfaces()); 
 }
 
 private static void createProxyClassFile(String name,Class<?> [] interfaces){
  byte[] data = ProxyGenerator.generateProxyClass(name,interfaces);//该方法为jdk中生成代理类的核心方法
  FileOutputStream out =null;
  try {
   out = new FileOutputStream(name+".class");
   System.out.println((new File(name)).getAbsolutePath());
   out.write(data);
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }finally {
   if(null!=out) try {
    out.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 } 
}

好奇心强的小伙伴一定看过newProxyInstance方法看过了,

里面的getProxyClass方法创建代理类:



Class<?> cl = getProxyClass0(loader, intfs);

具体是里面的哪个方法生成的,小伙伴们不用找半天了,慢慢debug后会发现,就是上面提到的


ProxyGenerator.generateProxyClass()

通过该方法生成的代理类如下:

通过反编译查看源码,一看便知接口的作用

JDK的动态代理是靠多态和反射来实现的,它生成的代理类需要实现你传入的接口,并通过反射来得到接口的方法对象(下文中的m3),并将此方法对象传参给增强类(上文中的WavingInvocationHandler类)的invoke方法去执行,从而实现了代理功能,故接口是jdk动态代理的核心实现方式,没有它就无法通过反射找到方法,所以这也是必须有接口的原因。不知道大家明白否


public final class test12345 extends Proxy implements SayService {
    //1、该类实现你传入的接口并实现方法 
    // 2、通过构造方法传入你定义的增强类对象 
    // 3、通过反射该接口,得到接口里的Method对象并传参给增强类,然后执行Invoke实现功能
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;
 
    public test12345(InvocationHandler paramInvocationHandler) {
        super(paramInvocationHandler);//2.此处的super指向Proxy中的构造方法并赋值(下文的h就是此处的增强类对象),
    }
 
    //略去无关的hashcode和equals方法
    public final void say(String paramString) {
        try {
            this.h.invoke(this, m3, new Object[]{paramString});//3.此处的h就是InvocationHandler对象,invoke就是你增强类里的方法,传入接口的方法和参数并执行你增强类里的invoke方法,即完成了整个操作!
        } catch (Error | RuntimeException localError) {
            throw localError;
        } catch (Throwable localThrowable) {
            throw new UndeclaredThrowableException(localThrowable);
        }
    }
 
    static {//1.静态代码块给属性赋值,初始化接口中的方法对象(主要是下面的m3)
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m3 = Class.forName("com.chenrui.core.jdk.SayService").getMethod("say", new Class[]{Class.forName("java.lang.String")});
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
        } catch (NoSuchMethodException localNoSuchMethodException) {
            throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
        } catch (ClassNotFoundException localClassNotFoundException) {
            throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
        }
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: JDK动态代理,代理接口没有实现类,实现动态代理方式

本文链接: https://lsjlt.com/news/133398.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JDK动态代理,代理接口没有实现类,实现动态代理方式
    目录JDK动态代理,代理接口没有实现类,实现动态代理被代理的接口:代理对象:那么接下来测试一下:jdk动态代理为什么要接口先通过一个简单例子实现功能:编写测试方法:里面的getPro...
    99+
    2024-04-02
  • Java如何实现JDK动态代理
    这篇文章主要讲解了“Java如何实现JDK动态代理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java如何实现JDK动态代理”吧!概念代理:为控制A对象,而创建出新B对象,由B对象代替执行...
    99+
    2023-07-02
  • 纯手写实现JDK动态代理
    作者:张丰哲原文:https://www.jianshu.com/p/58759fef38b8前言在Java领域,动态代理应用非常广泛,特别是流行的Spring/MyBatis等框架。JDK本身是有实现动态代理技术的,不过要求被代理的类必须...
    99+
    2023-06-02
  • 基于jdk动态代理和cglib动态代理实现及区别说明
    目录jdk动态代理和cglib动态代理实现及区别jdk动态代理实现cglib动态代理区别总结jdk动态代理和cglib动态代理实现及区别 代理模式是一种设计模式,提供了对目标对象额外...
    99+
    2023-05-19
    jdk动态代理 cglib动态代理 jdk和cglib动态代理区别
  • jdk动态代理和cglib动态代理详解
    目录静态代理基于继承的方式实现静态代理基于聚合的方式实现静态代理继承与聚合方式实现的静态代理对比动态代理JDK动态代理如何实现一个HashMap的动态代理类?Cglib动态代理JDK...
    99+
    2024-04-02
  • JDK和CGLib动态代理怎么实现
    本篇内容介绍了“JDK和CGLib动态代理怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言:动态代理是一种常用的设计模式,广泛应用...
    99+
    2023-06-02
  • java动态代理实现代码
    目录1、代理模式2、动态代理3、原理研究4、应用5、总结1、代理模式 代理模式是常用的设计模式之一,也是开发中常见的设计模式。 简单的描述一下,代理模式就是将实现类隔离开,比如你想给...
    99+
    2024-04-02
  • 解读jdk动态代理为什么必须实现接口
    目录使用jdk生成代理类生成代理的字节码总结使用jdk生成代理类 通过jdk实现的动态代理会使用Proxy的newProxyInstance方法: 写一个类实现Invocation...
    99+
    2023-02-17
    jdk动态代理 jdk代理 jdk动态代理接口
  • Java实现JDK动态代理的原理详解
    目录概念案例静态代理JDK动态代理模式原理分析真相大白概念 代理:为控制A对象,而创建出新B对象,由B对象代替执行A对象所有操作,称之为代理。一个代理体系建立涉及到3个参与角色:真实...
    99+
    2024-04-02
  • Java——JDK动态代理
    1.动态代理 1.1什么是动态代理? 动态代理(理解) 基于反射机制 举个例子,生活中一般在打官司的时候都会请代理律师,为什么要请律师呢?是因为开庭的时候大部人对于打官司没有经验,只会说出自己案件的陈述,并不会根据法律等争取自己权益...
    99+
    2023-08-31
    java 开发语言
  • 代理模式:JAVA静态代理和动态代理的实例和实现详解
    目录前言静态代理实现简述创建human接口创建接口实现类创建针对接口实现增强操作的代理代理实现效果动态代理实现简述要点:向上转型创建YoungMan接口创建两个接口实现类创建动态代理...
    99+
    2024-04-02
  • 深入理解java动态代理的两种实现方式(JDK/Cglib)
    什么是代理模式?代理模式:在调用处不直接调用目标类进行操作,而是调用代理类,然后通过代理类来调用目标类进行操作。在代理类调用目标类的前后可以添加一些预处理和后处理操作来完成一些不属于目标类的功能。为什么要使用代理模式?通过代理模式可以实现对...
    99+
    2023-05-31
    cglib jdk java
  • java代理模式(静态代理、动态代理、cglib代理)
    目录代理模式静态代理代码接口被代理对象代理对象测试动态代理代码:接口目标对象代理对象测试cglib代理代码:目标对象代理对象测试应用总结代理模式 代理模式(Proxy Pattern...
    99+
    2024-04-02
  • Java 动态代理的多种实现方式
    目录一、动态代理简介二、动态代理的多种实现 1. 基于JDK的实现 2. 基于cglib的实现 三、为什么要有基于cglib的实现 四、两种方式的适用场景JDK动态代理 优点 缺点 ...
    99+
    2024-04-02
  • java动态代理的实现方法
    这篇文章主要介绍“java动态代理的实现方法”,在日常操作中,相信很多人在java动态代理的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java动态代理的实现方法”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-20
  • Java实现动态代理的实例代码
    目录前言静态代理 动态代理 CGLib实现动态代理 总结前言 动态代理在Java中有着广泛的应用,比如Spring AOP、Hibernate数据查询、测试框架的后端mock、RPC...
    99+
    2024-04-02
  • Spring Core动态代理的实现代码
    目录1.设计原理2.ProxyFactory (Spring-Core)2.1 JdkDynamicAopProxy2.2 CglibAopProxy2.3 主要源码部分1.设计原理...
    99+
    2024-04-02
  • 使用Java怎么实现静态代理和动态代理
    本篇文章为大家展示了使用Java怎么实现静态代理和动态代理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。代理模式代理模式(Proxy):为其他对象提供一个代理以控制对这个对象的访问。主要解决:在直接...
    99+
    2023-06-14
  • Java动态代理模式怎么实现
    这篇文章主要介绍“Java动态代理模式怎么实现”,在日常操作中,相信很多人在Java动态代理模式怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java动态代理模式怎么实现”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-17
  • 如何进行Java代理设计模式的静态代理和动态代理实现
    今天就跟大家聊聊有关如何进行Java代理设计模式的静态代理和动态代理实现,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。面试问题:Java里的代理设计模式一共有几种实现方式?这个题目很...
    99+
    2023-06-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作