Person接口

package com.zhoucong.proxy.jdk;

public interface Person {

//    寻找真爱
void findlove(); }

人物实现类

package com.zhoucong.proxy.jdk;

public class Zhangsan implements Person{

    @Override
public void findlove() {
System.out.println("我叫张三,性别女,我找对象的要求如下:\n");
System.out.println("高富帅");
System.out.println("有房有车");
System.out.println("身高180cm以上,体重70kg");
} }

自定义InvocationHandler接口

package com.zhoucong.custom;

import java.lang.reflect.Method;

public interface GPInvocationHandler {

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

代理类

package com.zhoucong.custom;

import java.lang.reflect.Method;

import com.zhoucong.proxy.jdk.Person;

public class GPMeiPo implements GPInvocationHandler{

    private Person target;

//  获取被代理人的个人资料
public Object getInstance(Person target) throws Exception {
this.target = target;
Class clazz = target.getClass();
System.out.println("被代理对象的class是:"+ clazz);
return GPProxy.newProxyInstance(new GPClassLoader(), clazz.getInterfaces(), this); } @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是媒婆!");
System.out.println("开始信息海选");
System.out.println("-------------");
method.invoke(this.target, args);
System.out.println("-------------");
System.out.println("如果合适的话,就准备办事");
return null;
} }

生成代理对象类

package com.zhoucong.custom;

import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider; /**
* 生成代理对象的代码
*
* @author ZhouCong
*
*/
public class GPProxy { private static String ln = "\r\n"; public static Object newProxyInstance(GPClassLoader loader, Class<?>[] interfaces, GPInvocationHandler h)
throws IllegalArgumentException {
try {
// 1.生成源代码
String proxySrc = generateSrc(interfaces[0]); // 2.将生成的源代码输出到磁盘,保存.java文件
String path = GPProxy.class.getResource("").getPath();
File f = new File(path + "$Proxy0.java");
FileWriter fw = new FileWriter(f);
fw.write(proxySrc);
fw.flush();
fw.close(); // 3.编译源代码,并且生成.class文件
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
Iterable iterable = manager.getJavaFileObjects(f);
CompilationTask task = compiler.getTask(null, manager, null, null, null, iterable);
task.call();
manager.close(); // 4.将class文件中的内容,动态加载到JVM中
Class<?> proxyClass = loader.findClass("$Proxy0");
Constructor<?> constructor = proxyClass.getConstructor(GPInvocationHandler.class);
f.delete(); //删除生成的Java文件 // 5.返回被代理后的代理对象
return constructor.newInstance(h); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
} /**
* 生成代码
* @param interfaces
* @return
*/
private static String generateSrc(Class<?> interfaces) { StringBuffer src = new StringBuffer();
src.append("package com.zhoucong.custom;" + ln);
src.append("import java.lang.reflect.Method;" + ln);
src.append("public class $Proxy0 implements " + interfaces.getName() + "{" + ln);
src.append("GPInvocationHandler h;" + ln);
src.append("public $Proxy0(GPInvocationHandler h){" + ln);
src.append("this.h = h;" + ln);
src.append("}" + ln); for (Method m : interfaces.getMethods()) {
src.append("public " + m.getReturnType().getName() + " " + m.getName() + "() {" + ln);
src.append("try {" + ln);
src.append("Method m = " + interfaces.getName() + ".class.getMethod(\"" + m.getName() +"\",new Class[]{});" + ln);
src.append("this.h.invoke(this,m,null);" + ln);
src.append("} catch(Throwable e){e.printStackTrace();}" + ln);
src.append("}" + ln);
} src.append("}");
return src.toString();
};
}

自定义ClassLoader类

package com.zhoucong.custom;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; /**
* 代码生成、编译、重新动态load到JVM中
* @author ZhouCong
*
*/
public class GPClassLoader extends ClassLoader{ private File baseDir; public GPClassLoader() {
String path = GPClassLoader.class.getResource("").getPath();
this.baseDir = new File(path);
} @Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String className = GPClassLoader.class.getPackage().getName() + "." + name;
if(baseDir != null) {
File classFile = new File(baseDir,name.replaceAll("\\.", "/")+".class");
if(classFile.exists()) {
FileInputStream in = null;
ByteArrayOutputStream out = null;
try {
in = new FileInputStream(classFile);
out = new ByteArrayOutputStream();
byte [] buff = new byte[1024];
int len;
while((len = in.read(buff)) != -1) {
out.write(buff,0,len);
}
return defineClass(className,out.toByteArray(),0,out.size()); }catch (Exception e) {
e.printStackTrace();
}finally { if(null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 删除class文件
classFile.delete();
}
} } return null;
} }

运行类

package com.zhoucong.proxy.jdk;

import com.zhoucong.custom.GPMeiPo;

public class TestFindLove {

    public static void main(String[] args) {

        try {

            Person obj = (Person) new GPMeiPo().getInstance(new Zhangsan());
System.out.println(obj.getClass());
obj.findlove();
} catch (Exception e) {
e.printStackTrace();
}
} }

手写实现JDK的动态代理的更多相关文章

  1. JDK动态代理深入理解分析并手写简易JDK动态代理(下)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-05/27.html 作者:夜月归途 出处:http://www.guitu ...

  2. JDK动态代理深入理解分析并手写简易JDK动态代理(上)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-03/27.html 作者:夜月归途 出处:http://www.guitu ...

  3. JAVA JDK的动态代理反射实现

    动态代理类使用到了一个接口InvocationHandler和一个代理类Proxy ,这两个类配合使用实现了动态代理的功能. 什么是动态代理呢?  普通代理类是指: 给每个具体类写一个代理类,以后要使 ...

  4. jdk的动态代理

    至于jdk的动态代理怎么用此处并不多说,现在是更深一步的理解,jdk的Proxy类到底做了什么. Proxy.newProxyInstance可以生成代理类,此方法有三个参数(ClassLoader ...

  5. 基于 JDK 的动态代理机制

    『动态代理』其实源于设计模式中的代理模式,而代理模式就是使用代理对象完成用户请求,屏蔽用户对真实对象的访问. 举个最简单的例子,比如我们想要「FQ」访问国外网站,因为我们并没有墙掉所有国外的 IP,所 ...

  6. JDK的动态代理机制

    JDK Proxy OverView jdk的动态代理是基于接口的,必须实现了某一个或多个随意接口才干够被代理,并且仅仅有这些接口中的方法会被代理.看了一下jdk带的动态代理api.发现没有样例实在是 ...

  7. JDK 原生动态代理是怎么实现的 + 面试题

    JDK 原生动态代理是怎么实现的 + 面试题 反射 反射机制是 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect)的能力.简单来说就是通过反射,可以在运行期间获取.检测和调 ...

  8. 代理模式详解:静态代理+JDK/CGLIB 动态代理实战

    1. 代理模式 代理模式是一种比较好的理解的设计模式.简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标 ...

  9. JDK的动态代理-----为接口进行代理

    JDK的动态代理是必须掌握的,动态代理的好处就不用我多说了吧 :) 小弟最近在研究mybatis的源码实现,就开始了解mybatis的Mapper代理机制,为什么接口不用实现类也能代理? 好了,废话不 ...

随机推荐

  1. PyQt(Python+Qt)学习随笔:gridLayout的layoutRowStretch和layoutColumnStretch属性

    Qt Designer中网格布局中,layoutRowStretch和layoutColumnStretch两个属性分别设置网格布局中行之间和列之间的拉伸因子,如图: 但是QGridLayout并没有 ...

  2. linux常用快捷键总结

    启动器:<super> 显示桌面:<super>D 文件管理器:<super>E 显示工作区:<super>S 打开终端:ctrl+alt+T 关闭窗口 ...

  3. 2、pytorch——Linear模型(最基础版,理解框架,背诵记忆)(调用nn.Modules模块)

    #define y = X @ w import torch from torch import nn #第一模块,数据初始化 n = 100 X = torch.rand(n,2) true_w = ...

  4. Django官方为什么没有标准项目结构

    Django官方并没有提供标准的项目结构,于是网上众说纷纭,百花齐放,一千个读者有一千个哈姆雷特.那我们该怎么设计项目结构呢?在回答这个问题之前,先了解一下Django原生的目录和文件都是干嘛的. p ...

  5. 数据结构,哈希表hash设计实验

    数据结构实验,hash表 采用链地址法处理hash冲突 代码全部自己写,转载请留本文连接, 附上代码 #include<stdlib.h> #include<stdio.h> ...

  6. Pytest 系列(27)- allure 命令行参数

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 先看看 allure 命令的帮助文 ...

  7. 前端开发超好用的截图、取色工具——snipaste

    最近发现一个很好用的前端截图,取色工具,并且基本功能是免费使用的,可以提升开发效率,拿出来跟大家分享一下. 该工具主要能实现的功能就是截图,并且截图可以以窗口形式置顶在窗口: 第二个主要功能就是可以取 ...

  8. AOP基本概念

    连接点joinpoint(类中所有方法) 切入点pointcut(缺少共性代码的方法) 通知advice(被抽取的共性功能的代码逻辑,通知有位置区分,也就是从切入点方法中被抽取代码的前面还是后面抽象出 ...

  9. 【Tomcat 源码系列】Tomcat 整体结构

    一,前言 在开始看源码细节之前,首先要想好要看的问题.想好问题之后,我们该如何寻找要看的代码呢? 其实,这就好像去爬山的时候,突然想去上厕所,如果有一副地图,那么我们可以很快就找到厕所的位置.带着问题 ...

  10. 开发阶段,将SpringBoot应用快速部署到K8S

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...