首页 > 编程语言 >java动态代理

java动态代理

时间:2023-08-08 18:22:27浏览次数:36  
标签:java target invoke Object 代理 实例 动态 method

动态代理

代理比较好理解,和现实生活中意思一样。就是我要干一件事情,可以通过代理人或代理平台进行完成,不需要直接和服务方接触。
又或者计算机网络上说的代理。为什么叫动态代理?
这里回到java程序上,是因为在运行时可以动态的创建接口的实现,通过java的反射进行实现。依赖三个关键类:Proxy、Method和InvocationHandler.

创建代理实例

使用Proxy类的newProxyInstance方法

/**
    loader是类加载器
    interfaces 被代理的类,这里只支持接口
    InvocationHandler 代理处理handler
*/
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h){}

要创建代理实例,我们就要准备三个参数:第一个类加载器用来动态加载class文件。第二个参数需要动态代理的接口。第三个参数代理处理handler。创建被代理实例
都会调用该handler的invoke方法。

InvocationHandler只有一个接口方法

public interface InvocationHandler{
  Object invoke(Object proxy, Method method, Object[] args)
         throws Throwable;
}

invoke方法持有三个参数:
proxy代理实例对象,就是newProxyInstance创建的实例,目前没有发现有哪些用处
method被代理方法实例。这里就可以通过反射获取方法定义相关的信息。
args调用方法实例参数。

invoke方法体就是具体我们要对代理方法进行增强的操作逻辑。一般情况下我们在一些操作后还要执行原先method的方法逻辑,当然你也可以完全修改原逻辑。学过反射都知道
通过反射执行method.invoke(target, args)。需要target实例对象,args参数。这里参数已经有了,还差target实例。所以一般在实现InvocationHandler接口的时候
还会把target对象传进来。

完整的一个代理例子:

public class DynamicProxyTest {

    static class DyInvokeHandler implements InvocationHandler{

        public DyInvokeHandler(Object target){
            this.target = target;
        }
        //被代理实例对象
        private Object target;
        //这里proxy参数就是外面创建的代理对象proxyMap
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if("put".equals(method.getName()))
                System.out.println("invoke method:"+method.getName());
            return  method.invoke(target, args);
        }
    }

    public static void main(String[] args) {
        //创建Map接口的代理对象
        Map proxyMap = (Map) Proxy.newProxyInstance(DynamicProxyTest.class.getClassLoader(),
                new Class[]{Map.class},new DyInvokeHandler(new HashMap<>()));
        
        proxyMap.put("name","test");
        System.out.println(proxyMap.get("name"));
    }
}

使用场景

spring中的AOP切面编程还有依赖注入、事务的控制都是用的动态代理。日志记录,mock接口数据,权限控制其实都可以使用。

标签:java,target,invoke,Object,代理,实例,动态,method
From: https://www.cnblogs.com/bird2048/p/17615107.html

相关文章

  • JavaGuide
    Java基础知识点汇总0.Java语言特性简单易学具有面向对象三大特性:继承、封装、多态平台无关性(由JVM虚拟机实现与平台无关)可靠性安全性支持多线程支持网络编程编译与解释并存与C++相比:都是面向对象的语言,都支持继承封装多态Java不提供指针来直接访问内存,更加安全Jav......
  • 学习Java第16天
    Scanner对象之前我们学的基本语法中文名并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。Java.util.Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入基本语法:Scanners=newScanner(System.in)通过Scanner类的ne......
  • JavaScript实现文件夹的上传和下载
    ​ASP.NET上传文件用FileUpLoad就可以,但是对文件夹的操作却不能用FileUpLoad来实现。下面这个示例便是使用ASP.NET来实现上传文件夹并对文件夹进行压缩以及解压。ASP.NET页面设计:TextBox和Button按钮。 ​编辑TextBox中需要自己受到输入文件夹的路径(包含文件夹),通过Button......
  • 跳表及其Java实现
    跳表及其实现参考https://zhuanlan.zhihu.com/p/339750543importjava.util.Objects;importjava.util.Random;importjava.util.Stack;/***参考https://zhuanlan.zhihu.com/p/339750543*/publicclassSkipListPractice{staticclassSkipNode<T>{S......
  • Sqoop 连接mysql 错误 java.lang.NoClassDefFoundError(已解决)
    错误信息Exceptioninthread"main"java.lang.NoClassDefFoundError:org/apache/commons/lang/StringUtilsatorg.apache.sqoop.manager.MySQLManager.initOptionDefaults(MySQLManager.java:73)atorg.apache.sqoop.manager.SqlManager.<init......
  • 代理IP与Socks5代理:跨界电商、游戏和爬虫领域的技术赋能与安全保障
    一、代理IP技术简介与特点代理IP技术是通过中间服务器转发网络请求,隐藏用户真实IP地址的技术。它可以实现匿名访问、突破封锁和数据隐私保护等功能。代理IP的分类:常见的代理IP类型包括HTTP代理、HTTPS代理和Socks代理,其中Socks5代理是最为灵活和高效的代理技术之一。二、Socks5代理......
  • java heap space解决方法
    在JVM中如果98%的时间是用于GC(Garbage Collection)且可用的Heapsize不足2%的时候将抛出异常信息,java.lang.OutOfMemoryError:Javaheapspace。所以产生这个异样的原因通常有两种:1.程序中出现了死循环2.程序占用内存太多,超过了JVM堆设置的最大值。对于第一种情况,需要自己查看......
  • asterisk-java的测试使用
    asterisk-java的测试使用一个可用于FreePBX的封装库asterisk-java用于asteriskPBX集成的免费Java库。https://github.com/asterisk-java/asterisk-java最新版本为3.39.0<dependency><groupId>org.asteriskjava</groupId><artifactId>asterisk-java</artifactId><......
  • Java入门题-查找一个字符串中,所有想查找短字符串的起始位置
    问题:就是长短两串字符串,从长字符串中查找所有短字符串在长字符串中的位置方法:用截取方式来规避已经查找过的内容,重复遍历来确定位置代码:需要引用importjava.util.Scanner; Scanners=newScanner(System.in);//新定义一个ScannerStringS=s.next();......
  • JAVA 问题记录
     OOM(内存溢出) 先查看java进程pidjps使用jmp把内存导出查看那些对象内存占用比较高jmp-histo<pid>>/histo.txt在可以看堆内存使用情况jmp-heap<pid>>/heap.txt ......