java的动态代理如何实现

news2025/1/16 16:05:31

一. JdkProxy

jdkproxy动态代理必须基于接口(interface)实现

  1. 接口UserInterface.java
public interface UserService {
	String getUserName(String userCde);
}
  1. 原始实现类:UseServiceImpl.java
public class UserServiceImpl implements UserSerice {
	@Override
	public String getUserName(String userCde) {
		System.out.println("the name of " + userCde + "is Austin");
        return "Austin";
	}
}
  1. 代理类 :UserProxyFactoryBJdk.java
public class UserProxyFactoryBJdk {
	public static UserService getUserServiceProxy(UserService origin) {
        UserService userService = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader()
                , new Class[]{UserService.class}
				, new InvocationHandler() { //动态代理实现类
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("before");
                        Object o = method.invoke(origin, args);
                        System.out.println("after");
                        return o;
                    }
                });
        return userService;
    }

    public static void main(String[] args) {
        UserService userService = getUserServiceProxy(new UserServiceImpl());
        userService.getUserName("123");
    }
}

执行结果:
before
the name of 123is Austin
after

二. Cglib动态代理

Cglib实现动态代理与JdkProxy不同, 是通过构建继承类实现

  1. 原始类UseServiceImpl.java
public class UserServiceImpl implements UserSerice {
	@Override
	public String getUserName(String userCde) {
		System.out.println("the name of " + userCde + "is Austin");
        return "Austin";
	}
}
  1. 代理类 :UserProxyFactoryByCglib.java
public static UserServiceImpl getUserServiceProxy(UserService origin) {
        Enhancer enhancer = new Enhancer();
        // 设置debug信息
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY
                , "/home/aa/dev/testfile/com/austin/meta/cxf/");
        // 设置父类:UserServiceImpl
        enhancer.setSuperclass(UserServiceImpl.class);
        //设置代理实现逻辑
        enhancer.setCallback(new CglibInterCeptor() {
        	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("CglibInterCeptor.intercept-before");
        Object o = proxy.invokeSuper(obj, args);
        System.out.println("CglibInterCeptor.intercept-after");
        return o;
    }
        });
        UserServiceImpl userService = ((UserServiceImpl) enhancer.create());
        return userService;
    }

    public static void main(String[] args) {
        UserService userService = getUserServiceProxy(new UserServiceImpl());
        userService.getUserName("123");
    }

  1. 执行结果
    CglibInterCeptor.intercept-before
    the name of 123is Austin
    CglibInterCeptor.intercept-after

三. Java动态编译

通过JavaCompiler动态编译java源文件,并将相应字节码加载到JVM中,其编译底层通过javac -d 命令进行编译

  1. 需要动态编译的类文件
package com.austin.meta.dynamiccompiler;
public class UserServiceImplE extends UserServiceImpl {
    public UserServiceImplE() {
    }
    public String getUserName(String userCde) {
        System.out.println("before");
        super.getUserName(userCde);
        System.out.println("after");
        return "Austin";
    }
}
  1. 动态编译类
public class JavaCompilerTest {
	private static String basePath = "";
	public static void main(String[] args) throws Exception{
        System.out.println(ClassLoader.getSystemResource(""));
        Class<?> userServiceImplE = compiler("UserServiceImplE");
        UserServiceImpl o = (UserServiceImpl)userServiceImplE.getConstructor(null).newInstance(null);
        o.getUserName("235");

    }
  private static Class<?> getClass(String pakcge, String className) {
        Class<?> clazz = null;
        try {
            clazz = Class.forName(pakcge + "." +className, true, JavaCompilerTest.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return clazz;
    }
   /**
   * 动态编译java类,并通加载到JVM
   */
private static Class<?> compiler(String className) throws IOException {
        File javaSrcFile = new File(basePath+ "/" + className + ".java");
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
        List<String> options = Arrays.asList("-d", ClassLoader.getSystemResource("").toString());
        JavaCompiler.CompilationTask task = compiler.getTask(null
                , standardFileManager, null, options, null, standardFileManager.getJavaFileObjects(javaSrcFile));
        Boolean isCompilerSuccess = task.call();
        if(!isCompilerSuccess) {
            return null;
        }
        Class<?> clazz = getClass("com.austin.meta.dynamiccompiler", className);
        return clazz;
    }
}

  1. 执行结果
    before
    the name of 235is Austin
    after

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

布局过程的完全解析

前言 那么为什么要分为两个流程呢 因为测量流程是一个复杂的流程&#xff0c;有时候不一定一遍就能得出测量结果&#xff0c;可能需要 2 - 3 次甚至更多 自定义布局的几种类型&#xff0c;也是自定义布局的两个方法 实战&#xff0c;第一种类型&#xff1a;改写已有View 的步骤…

day34 Map Properties

Map<String,Integer> map new HashMap<>(); map.put("a",1);map.put("b",2);map.put("c",3);map.put("d",4);Integer a map.put("a", 2);System.out.println(a);Integer chinese map.put("语文",1…

新一代G7系列浪潮云海超融合EC纠删功能设计

浪潮云海在2023年5月正式发布新一代InCloud Rail G7系列超融合一体机&#xff0c;其内置的InCloud dSAN超融合存储组件&#xff0c;基于新一代的硬件平台设计&#xff0c;支持全栈RDMA协议&#xff0c;同时在EC纠删功能上也带来全新体验&#xff0c;为新时代用户提供更丰富的产…

PYTHON(一)——认识python、基础知识

一、为什么要学习python&#xff1f; Python 被认为是人工智能、机器学习的首选语言&#xff0c;可以说是全世界最流行通用范围最广的语言&#xff0c;几乎可以完成所有的任务&#xff0c;像设计游戏、建网站、造机器人甚至人工智能等都广泛使用Python。 二、输出&#xff08;…

注解-宋红康

目录 一、注解&#xff08;Annotation&#xff09;概述二、常见的注解实例三、如何自定义注解四、JDK中的四个元注解五、Java8注解的新特性1、可重复注解2、类型注解 一、注解&#xff08;Annotation&#xff09;概述 二、常见的注解实例 三、如何自定义注解 自定义注解必须配…

查询硬盘序列号、物理地址及对应批处理命令

首先说明&#xff1a; 通过winR -> cmd -> diskpart -> list disk -> select disk 0 -> detail disk -> 然后显示磁盘ID等&#xff0c;这不是序列号&#xff0c;只是磁盘ID而已。 查询序列号命令很简单&#xff1a; wmic diskdrive get serialnumber或者 w…

权限、认证与授权

权限、认证与授权 1、权限概述 &#xff08;1&#xff09;什么是权限 权限管理&#xff0c;一般指根据系统设置的安全策略或者安全规则&#xff0c;用户可以访问而且只能访问自己被授权的资源&#xff0c;不多不少。权限管理几乎出现在任何系统里面&#xff0c;只要有用户和…

webstorm HbuilderX工具未配置

问题&#xff1a;调试动迁uni app h5项目&#xff0c;报错 webstorm是换了电脑新安装&#xff0c; HBuilerx是从旧电脑拷贝过来的解压的文件 解决&#xff1a; 把uniapp插件&#xff0c;卸载 再重启webstorm,重装安装uniapp Tool&#xff0c; 安装第一个&#xff0c;免费。…

拓展外部SRAM

外部拓展芯片 IS62WV51216A 芯片手册 支持高速时钟通道时间为45、55ns 芯片引脚定义 通道时序 读定义表 一个纵列表示当前使用的高速通道的时间&#xff0c;选一个纵列作为参数标准。 地址控制读时序 如图&#xff0c;大概需要三个参数 写时序定义表 还是选择55ns参数 写…

数据接口工程对接BI可视化大屏(五)数据接口发布

文章目录 第5章 数据接口发布5.1 编写Service5.2 从MySQL中返回数据5.2.*1 封装Bean5.2.*2 编写Mapper5.2.3 编写ServiceImpl5.2.4 编写Controller5.2.5 测试 5.3 从Redis中返回数据5.3.1 封装Bean5.3.2 编写Mapper5.3.3 编写ServiceImpl5.3.4 编写Controller5.3.5 测试 5.4 从…

day34 Set

概述 Set也是集合Collection接口的子接口 Set也是集合Collection接口的子接口 特点&#xff1a;不保证元素有顺序&#xff0c;数组元素不可以重复 HashSet: 底层是基于HashMap的。元素是无序的。元素不可重复&#xff0c;去重机制是依据hashCode()和equals()方法 LinkedHas…

数据结构-堆的实现及应用(堆排序和TOP-K问题)

数据结构-堆的实现及应用[堆排序和TOP-K问题] 一.堆的基本知识点1.知识点 二.堆的实现1.堆的结构2.向上调整算法与堆的插入2.向下调整算法与堆的删除 三.整体代码四.利用回调函数避免对向上和向下调整算法的修改1.向上调整算法的修改2.向下调整算法的修改3.插入元素和删除元素函…

vue学习之列表渲染

列表渲染 创建 demo8.html,内容如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</…

LeetCode算法心得——判断能否在给定时间到达单元格(动态模拟)

大家好&#xff0c;我是晴天学长&#xff0c;这是一个动态模拟题&#xff0c;跟大佬相比&#xff0c;我的有点繁琐了&#xff0c;但是也算是锻炼到自己的一些细节问题&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。 1) .判断能否在给定时间到达单元…

Pytorch面试题整理(2023.09.10)

1、pytorch如何微调fine tuning&#xff1f; 在加载了预训练模型参数之后&#xff0c;需要finetuning 模型&#xff0c;可以使用不同方式finetune。 局部微调&#xff1a;加载了模型参数后&#xff0c;只想调节最后几层&#xff0c;其他层不训练&#xff0c;也就是不进行梯度…

【Endnote】如何出现“作者(年份) found that ....”的格式?

如何出现“作者&#xff08;年份&#xff09; found that ....”的格式&#xff1f; 非常简单&#xff01;先用endnote插入文献后&#xff0c;默认显示&#xff1a; 然后&#xff0c;重点来了&#xff0c;点开这个&#xff1a; 然后&#xff0c;将此处的default改成Display as…

unique_ptr的大小探讨

unique_ptr大小和删除器有很大关系&#xff0c;具体区别看如下代码的分析。不要让unique_ptr占用的空间太大&#xff0c;否则不会达到裸指针同样的效果。 #include <iostream> #include <memory> using namespace std;class Widget {int m_x;int m_y;int m_z;publ…

国产化改造之Mysql迁移方案:Mysql Galera Cluster

一、背景 因某业务系统OS国产化改造&#xff0c;现需将生成环境Mysql 主从迁移到新部署的BCLinux OS主机上&#xff1b;如果保障业务不断&#xff0c;平滑迁移并成功割接将是本次方案的重要方向&#xff0c;现场环境涉及需迁移数据780G左右&#xff0c;目标主机OS版本&#xff…

day35 线程

程序&#xff1a;是为了完成特定的任务&#xff0c;用某种语言编写的一组有序指令的集合&#xff0c;是一段静态的代码 进程&#xff1a;是程序的一次执行过程 线程&#xff1a;线程是进程中的一个执行单元 线程是调度和执行的单位 处理器和线程间的关系 创建线程(重点) 创建…

时序分解 | MATLAB实现MVMD多元变分模态分解信号分量可视化

时序分解 | MATLAB实现MVMD多元变分模态分解信号分量可视化 目录 时序分解 | MATLAB实现MVMD多元变分模态分解信号分量可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MVMD多元变分模态分解 可直接替换Excel运行包含频谱相关系数图 Matlab语言 1.算法新颖小众&…