0. 原理分析

a). 自定义实现InvocationHandler类,实现代理类执行时的invoke方法
b). 使用Proxy.newProxyInstance生成接口的代理类(入参还包括InvocationHandler)
c). 所有的proxyImpl.methodName都会被invoke方法拦截
d). 备注: 推荐反编译$Proxy0.查看
1 -- 设置系统参数以保存中间态生成的class文件, 文件名类似 $Proxy0.class
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true")
2 -- $Proxy0.class所在的目录 System.getProperty("user.dir")/com/sun/proxy/, 即执行java命令的目录下
IDEA和eclipse中是工程的根目录

1. 示例

1.1 示例1--直接代理接口(Mybatis的Mapper)

TestInterface.java
public interface TestInterface {
public void saySomething(String thing);
}
InvokeMethodClass.java
public class InvokeMethodClass implements InvocationHandler{
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入invoke方法!");
//method.invoke("zzzzzz");
System.out.println("invoke执行结束");
return null;
} public static void main(String[] args) {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true"); //保存中间态的代理类class到文件
TestInterface tt = (TestInterface) Proxy.newProxyInstance(TestInterface.class.getClassLoader(), new Class[]{TestInterface.class}, new InvokeMethodClass());
tt.saySomething("sssssss");
}
}

执行:

java -cp G:\practice\idea-new\ideaMaven\target\classes  test.java.proxytest.InvokeMethodClass
进入invoke方法!
invoke执行结束

1.2 示例2--代理接口实现类(Spring中AOP实现之一)

TestInterface.java
public interface TestInterface {
public void saySomething(String thing);
}
TestInterfaceImpl.java
public class TestInterfaceImpl implements TestInterface
{
public void saySomething(String thing) {
System.out.println("接口实现类的方法:"+thing);
}
}
InvokeMethodClass.java
public class InvokeMethodClass implements InvocationHandler { //需要代理的实现类
private Object impl; //生成代理类
public Object bind(Object impl) {
this.impl = impl;
return (TestInterface) Proxy.newProxyInstance(TestInterface.class.getClassLoader(), impl.getClass().getInterfaces(), this);
} //方法调用时触发的方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入invoke方法!");
method.invoke(impl, "zzzzzz");
System.out.println("invoke执行结束");
return null;
} public static void main(String[] args) {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
InvokeMethodClass invokeMethodClass = new InvokeMethodClass(); TestInterface tt = (TestInterface) invokeMethodClass.bind(new TestInterfaceImpl());
System.out.println("代理类的class:" + tt.getClass().getName()); tt.saySomething("sssssss");
}
}

执行结果:java -cp G:\practice\idea-new\ideaMaven\target\classes test.java.proxytest.InvokeMethodClass

代理类的class:com.sun.proxy.$Proxy0
进入invoke方法!
接口实现类的方法:zzzzzz
invoke执行结束

2. Proxy.newProxyInstance源码分析

Proxy.newProxyInstance() -->  Class<?> cl = getProxyClass0(loader, intfs);
--> proxyClassCache.get(); //proxyClassCache来自何处
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
WeakCache(BiFunction<K, P, ?> subKeyFactory,
BiFunction<K, P, V> valueFactory) {
this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
this.valueFactory = Objects.requireNonNull(valueFactory);
}
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
--> ProxyClassFactory.apply(); //生产
--> byte[] proxyClassFile = ProxyGenerator.generateProxyClass( //生成classFile
proxyName, interfaces, accessFlags);
--> if(saveGeneratedFiles) //是否保存生成的class文件,前面设置的系统参数及在此处
saveGeneratedFiles = ((Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles"))).booleanValue();

JDK动态代理详解-依赖接口的更多相关文章

  1. SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架

    1 JDK动态代理详解 静态代理.JDK动态代理.Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文. 1.1 JDK代理的基本步骤 >通过实现InvocationHandler接口来 ...

  2. JDK动态代理详解

    JDK动态代理是代理模式的一种,且只能代理接口.spring也有动态代理,称为CGLib,现在主要来看一下JDK动态代理是如何实现的? 一.介绍 JDK动态代理是有JDK提供的工具类Proxy实现的, ...

  3. 转:JDK动态代理为什么必须用接口以及与CGLIB的对比

    参考链接: JDK动态代理为什么必须用接口以及与CGLIB的对比 文章中提到:试验了JDK动态代理与CGLIB动态代理.从Spring的AOP框架介绍中得知对于使用接口的类,Spring使用JDK动态 ...

  4. JDK、CGlib动态代理详解

    Java动态代理之JDK实现和CGlib实现(简单易懂)      一 JDK和CGLIB动态代理原理 1.JDK动态代理 利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生 ...

  5. 基于SpringBoot实现AOP+jdk/CGlib动态代理详解

    动态代理是一种设计模式.在Spring中,有俩种方式可以实现动态代理--JDK动态代理和CGLIB动态代理. JDK动态代理 首先定义一个人的接口: public interface Person { ...

  6. JDK动态代理、CGLIB动态代理详解

    Spring的AOP其就是通过动态代理的机制实现的,所以理解动态代理尤其重要. 动态代理比静态代理的好处: 1.一个动态代理类可以实现多个业务接口.静态代理的一个代理类只能对一个业务接口的实现类进行包 ...

  7. 【spring基础】AOP概念与动态代理详解

    一.代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一 ...

  8. JDK动态代理为什么必须针对接口

    查看jdk的动态代理源码发现: 动态代理实际上是程序在运行中,根据被代理的接口来动态生成代理类的class文件,并加载class文件运行的过程,通过反编译被生成的$Proxy0.class文件发现: ...

  9. cgkib动态代理详解-不依赖接口,速度快

    1. cglib原理-不依赖接口,速度快 使用ASM字节框架动态生成要代理类的子类,子类重写final以外的方法,织入横切逻辑 2. 示例-实现MethodInterceptor Test.java ...

随机推荐

  1. rufus-scheduler定时任务示例代码

    require 'rubygems' require 'rufus/scheduler' scheduler = Rufus::Scheduler.start_new scheduler.in '20 ...

  2. hibernate 持久化对象的生命周期

    持久化对象的生命周期 瞬态(自由态) 表示对象在内存中存在,在数据库中没有数据相关,比如刚刚new出来的一个对象 持久态 持久态指的是持久化对象处于由Hibernate管理的状态,这种状态下持久化对象 ...

  3. 拍照选择图片(Activity底部弹出)

    效果图如下: 第一步 : 显示出的布局文件:alert_dialog.xml <?xml version="1.0" encoding="utf-8"?& ...

  4. JAVA相关资料

    http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/ http://www.cnblo ...

  5. [xdoj1158]阶乘求逆元(常用于求组合数)

    http://acm.xidian.edu.cn/problem.php?id=1158 解题关键:此题注意将$\sum\limits_{i = 0}^x {C_x^iC_y^{i + k}}$转化为 ...

  6. 【PHP】composer 常用命令

  7. jQuery学习2

    1,jQuery中的$有什么意义. $是 JQuery 常用的一个回传函数. 很多人写jquery代码是这样开始的 $(function(){ // do something }); 事实上它是jqu ...

  8. ps&CPU

    #include <pthread.h> void f();int main() {        f();        return 0;} void f() {        int ...

  9. 【Qt官方例程学习笔记】Application Example(构成界面/QAction/退出时询问保存/用户偏好载入和保存/文本文件的载入和保存/QCommandLineParser解析运行参数)

    The Application example shows how to implement a standard GUI application with menus, toolbars, and ...

  10. 使用VS Code配合Remote Development插件连接远程服务器(Mac/Linux+Windows) | Using VS Code with Remote Development Connect to Remote Server (Mac/Linux+Windows)

    最新版VS Code(2019年6月)出了一系列新的插件,包括Remote Development,Remote SSH等,使得用户可以使用VS Code远程连接服务器写代码,方便了协同工作.具体配置 ...