请选择 进入手机版 | 继续访问电脑版

代理-JDK动态字节码获取($Proxy)

发表于 2017-07-11 23:06 显示全部楼层 16 295

时隔大半年,终于想起小码哥社区的会员账号密码, 好,现在继续将装逼事业进行到底。

上上篇代理-JDK动态代理原理:$Proxy 教大家使用 javaagent的方式获取java jdk 动态代理生成的字节码文件,有种强行装逼之嫌。而近期又用到代理,所以,通读源码后发现2种更加快捷的方式。分享出来给大家乐乐,有机会也可以拿来装装逼。

先上代码:

image.png

环境准备:总共有4个类:

IUSB:业务接口

USBImpl:业务接口实现类(真实对象, 将要被代理的对象)

USBJDKInvocationHandler:动态代理接口处理类

App:测试类

详细代码:

IUSB:

package com.langfei;

//业务接口
public interface IUSB {
	void swapData();
}

USBImpl:

package com.langfei;

//业务接口实现类
public class USBImpl implements IUSB{
	@Override
	public void swapData() {
		System.out.println("你傻逼....");
	}
}

USBJDKInvocationHandler:

package com.langfei;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//动态代理接口处理类
public class USBJDKInvocationHandler implements InvocationHandler{
	
	//真实对象(被代理的对象)
	private Object target;
	public USBJDKInvocationHandler(Object target){
		this.target = target;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("被代理....");
		return method.invoke(this.target, args);
	}
	
	@SuppressWarnings("unchecked")
	public <T> T getProxyObject(){
		return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				this.target.getClass().getInterfaces(), this);
	}
}

第一种方式:

package com.langfei;

import java.io.File;
import java.io.FileOutputStream;

import sun.misc.ProxyGenerator;

public class App {
	public static void main(String[] args) throws Exception {
		//ProxyGenerator:sun.misc.ProxyGenerator 是sun包,需要额外下载
		//ProxyGenerator.generateProxyClass 这个方法是从jdk动态代理源码中扣出来的方法
		//扣的过程,具体如下图
		byte[] classData = ProxyGenerator.generateProxyClass("$Proxy.class", USBImpl.class.getInterfaces());
		//保存到指定的路径的文件中
		FileOutputStream out = new FileOutputStream(new File("$Proxy.class"));
		out.write(classData);
		out.close();
		
	}
}

扣图:

image.png

运行之后,会在项目的根目录项生成指定名称的字节码文件

$Proxy.class 反编译之后可以得到这个篇代理-JDK动态代理原理:$Proxy 文中说到的$Proxy类。

第一种方法到这个里结束了,如果单纯想装装逼,也差不多了, 如果,还觉得逼格不够高, 继续第二种:

第二种:

public class App {
	public static void main(String[] args) throws Exception {
		//在系统属性中配置:sun.misc.ProxyGenerator.saveGeneratedFiles
		System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
		USBJDKInvocationHandler jdkHandler = new USBJDKInvocationHandler(new USBImpl());
		IUSB proxyObject = jdkHandler.getProxyObject();
		proxyObject.swapData();
	}
}

运行之后,会在项目根目录中生成一个$Proxy.class字节码文件:

image.png

原理是什么?

下载:sun.misc.ProxyGenerator.java文件,这个文件在sun.zip文件中, 

image.png

这个地方说到,当系统配置了这个属性,且值为true时,运行动态代理,会在根目录下生产代理对象$Proxy.class文件

到这,jdk的动态代理就搞掂。下次有空再说cglib的动态代理原理。



评分

参与人数 1学币 +5 收起 理由
seemygo + 5 全力支持你的装逼事业!

查看全部评分

回复 使用道具
举报
炒菜不加盐

发表于 2017-08-28 08:13 显示全部楼层

666

回复 支持 反对 使用道具
举报
PPAP!

发表于 2017-08-19 04:25 显示全部楼层

回复 支持 反对 使用道具
举报
望断雁南飞

发表于 2017-08-13 16:58 显示全部楼层

回复 支持 反对 使用道具
举报
甜甜车

发表于 2017-08-11 16:52 显示全部楼层

回复 支持 反对 使用道具
举报
一鸣

发表于 2017-08-01 17:38 显示全部楼层

作为新人,在吧里不敢大声说话,也不敢得罪人,只能默默地顶完贴转身就走,不求深藏功与名,只求前排混脸熟

回复 支持 反对 使用道具
举报
陈小呆

发表于 2017-07-30 07:23 显示全部楼层

每一个成功者都有一个开始。成功的路,始于回复。

回复 支持 反对 使用道具
举报
森之树

发表于 2017-07-27 16:00 显示全部楼层

好文章,必须帮顶!!!

回复 支持 反对 使用道具
举报
小明不易做

发表于 2017-07-25 17:27 显示全部楼层

回复 支持 反对 使用道具
举报
磁爆步兵杨永信

发表于 2017-07-19 13:57 来自手机 显示全部楼层

以诚感人者,人亦诚而应。一点回复,敬请笑纳!
回复 支持 反对 使用道具
举报
12下一页

发表新文章
叶星飞

小码哥骨干成员

0

学分

958

学币

1049

积分

小码哥骨干成员

Rank: 6Rank: 6

积分
1049
Ta的主页 发消息
精华帖排行榜

精彩推荐

  • 关注小码哥教育