JAVA-获取 JDK 动态代理生成的 Class 文件
可指定路径
- import sun.misc.ProxyGenerator;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- interface Dao {
- void save();
- }
- class DaoImpl implements Dao {
- @Override
- public void save() {
- System.out.println("save...");
- }
- }
- public class DynamicProxyTest {
- /**
- * 保存 JDK 动态代理生产的类
- * @param filePath 保存路径,默认在项目路径下生成 $Proxy0.class 文件
- */
- private static void saveProxyFile(String... filePath) {
- if (filePath.length == 0) {
- System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
- } else {
- FileOutputStream out = null;
- try {
- byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", DaoImpl.class.getInterfaces());
- out = new FileOutputStream(filePath[0] + "$Proxy0.class");
- out.write(classFile);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (out != null) {
- out.flush();
- out.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public static void main(String[] args) throws Exception {
- saveProxyFile();
- Object target = new DaoImpl();
- /**
- * loader:业务对象的类加载器
- * interfaces:业务对象实现的所有接口
- * public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces)
- */
- Class<?> proxyClass = Proxy.getProxyClass(DaoImpl.class.getClassLoader(), DaoImpl.class.getInterfaces());
- InvocationHandler handler = new InvocationHandler() {
- /**
- * @param proxy 代理对象
- * @param method 代理的方法对象
- * @param args 方法调用时参数
- */
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Object result = null;
- if (method.getName().equals("save")) {
- System.out.println("before...");
- result = method.invoke(target, args);
- System.out.println("after...");
- }
- return result;
- }
- };
- Dao userDao = (Dao) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
- userDao.save();
- }
- }
生成的代理类,方法调用会经过 InvocationHandler 对象
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.lang.reflect.UndeclaredThrowableException;
- final class $Proxy0 extends Proxy implements Dao {
- private static Method m1;
- private static Method m3;
- private static Method m2;
- private static Method m0;
- public $Proxy0(InvocationHandler var1) throws {
- super(var1);
- }
- public final boolean equals(Object var1) throws {
- try {
- return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
- } catch (RuntimeException | Error var3) {
- throw var3;
- } catch (Throwable var4) {
- throw new UndeclaredThrowableException(var4);
- }
- }
- public final void save() throws {
- try {
- super.h.invoke(this, m3, (Object[])null);
- } catch (RuntimeException | Error var2) {
- throw var2;
- } catch (Throwable var3) {
- throw new UndeclaredThrowableException(var3);
- }
- }
- public final String toString() throws {
- try {
- return (String)super.h.invoke(this, m2, (Object[])null);
- } catch (RuntimeException | Error var2) {
- throw var2;
- } catch (Throwable var3) {
- throw new UndeclaredThrowableException(var3);
- }
- }
- public final int hashCode() throws {
- try {
- return (Integer)super.h.invoke(this, m0, (Object[])null);
- } catch (RuntimeException | Error var2) {
- throw var2;
- } catch (Throwable var3) {
- throw new UndeclaredThrowableException(var3);
- }
- }
- static {
- try {
- m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
- m3 = Class.forName("javabase.dynamic.Dao").getMethod("save");
- m2 = Class.forName("java.lang.Object").getMethod("toString");
- m0 = Class.forName("java.lang.Object").getMethod("hashCode");
- } catch (NoSuchMethodException var2) {
- throw new NoSuchMethodError(var2.getMessage());
- } catch (ClassNotFoundException var3) {
- throw new NoClassDefFoundError(var3.getMessage());
- }
- }
- }
https://rejoy.iteye.com/blog/1627405
https://blog.csdn.net/lh513828570/article/details/74078773
https://blog.csdn.net/bestkilly/article/details/82141802
JAVA-获取 JDK 动态代理生成的 Class 文件的更多相关文章
- 深度剖析java中JDK动态代理机制
https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...
- 获取JDK动态代理/CGLIB代理对象代理的目标对象。
问题描述:: 我现在遇到个棘手的问题,要通过spring托管的service类保存对象,这个类是通过反射拿到的,经过实验发现这个类只能反射取得sservice实现了接口的方法,而extends类的方法 ...
- 获取动态代理生成的.class文件
生成代理类,并写入硬盘:配置系统属性sun.misc.ProxyGenerator.saveGeneratedFile为true,代理类生成时将自动将生成的代理类写入硬盘 ? 1 2 3 4 5 6 ...
- [编织消息框架][JAVA核心技术]jdk动态代理
需要用到的工具 jdk : javac javap class 反编译 :JD-GUI http://jd.benow.ca/ import java.lang.reflect.Invocation ...
- java之JDK动态代理
© 版权声明:本文为博主原创文章,转载请注明出处 JDK动态代理: JDK动态代理就是在程序运行期间,根据java的反射机制自动的帮我们生成相应的代理类 优势: - 1. 业务类只需要关注业务逻辑本身 ...
- Java基础-jdk动态代理与cglib动态代理区别
JDK动态代理 此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑. 代理模式在实际使用时需要指定具体的目标对象 ...
- 输出cglib以及jdk动态代理产生的class文件
--该设置用于输出jdk动态代理产生的类 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles&q ...
- Java基础-JDK动态代理
JDK的动态代理依靠接口实现 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...
- 设计模式之动态代理(Java的JDK动态代理实现)
先来看一下思维导图: 对于JDK的动态代理,孔浩老师说学习的方法是把它记下来. 先写一个主题接口类,表示要完成的一个主题. package com.liwei.dynaproxy; /** * 要代理 ...
随机推荐
- python 模块之-json
python 模块json import json x="[null,true,false,1]" print(json.loads(x)) #---------------- ...
- BZOJ3724PA2014Final Krolestwo——欧拉回路+构造
题目描述 你有一个无向连通图,边的总数为偶数.设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除).对于每个点对(u,v),你需要用一条长度为偶数(假设每条边长度为1)的 ...
- Codeforces Round #483 Div. 1
A:首先将p和q约分.容易发现相当于要求存在k满足bk mod q=0,也即b包含q的所有质因子.当然不能直接分解质因数,考虑每次给q除掉gcd(b,q),若能将q除至1则说明合法.但这个辣鸡题卡常, ...
- MySQL 同一台服务器同步数据
声明:我配置出来的slave_io_running和slave_sql_running都是yes.但是数据并没有同步! 希望有遇到相同问题的朋友,能够告诉我一下解决方案? 首先,如何在同一个服务器安装 ...
- C# Timer 的区别
首先,我们看一下 3种Timer 1.System.Threading.Timer 2.System.Timers.Timer 3.System.Windows.Forms.Timer 主要区别,其实 ...
- Codeforces1065G Fibonacci Suffix 【递推】【二分答案】
题目分析: 首先为了简便起见我们把前$15$的答案找出来,免得我们还要特判$200$以内之类的麻烦事. 然后我们从$16$开始递推.考虑猜测第i位是$0$还是$1$(这本质上是个二分).一开始先猜是$ ...
- 字符串哈希及KMP
字符串很神奇,因为它在计算机中应用很广泛,就每一个程序都需要用到字符串,所以学好字符串是非常重要的. 接下来就介绍两个字符串的基本操作 1:字符串hash 一种可以查找几个字符串有几个不同的字符串. ...
- maven "mvn不是内部或外部命令,也不是可运行的程序或批处理文件"
配置maven环境变量cmd控制台提示:mvn不是内部或外部命令,也不是可运行的程序或批处理文件 首先maven环境变量: 变量名:MAVEN_HOME 变量值:E:\apache-maven-3.2 ...
- MT【259】2016天津压轴题之最佳逼近
(2016天津压轴题)设函数$f(x)=(x-1)^3-ax-b,x\in R$, 其中$a,b\in R$(1)求$f(x)$的单调区间.(2)若$f(x)$存在极值点$x_0$,且$f(x_1)= ...
- BM算法
BM算法 用来求解一个数列的递推式. 即给定\(\{x_i\}\)求解一个\(\{a_i\}\),满足\(|a|=m,x_n=\sum_{i=1}^ma_i*x_{n-i}\). 考虑增量法构造. 假 ...