JDK的动态代理(powernode 文档)(内含源代码)
源代码下载链接地址:
https://download.csdn.net/download/weixin_46411355/87546086
一、动态代理
目录
- JDK的动态代理(powernode 文档)(内含源代码)
- `源代码下载链接地址:`[https://download.csdn.net/download/weixin_46411355/87546086](https://download.csdn.net/download/weixin_46411355/87546086)
- 一、动态代理
- 1.1JDK动态代理
- 1.1.1 proxy
- 1.1.2 InvocationHandler
- 1.1.3 创建一个Maven项目
- 1.1.4 导入Spring的相关依赖
- 1.1.5 修改包名为com.bjpowernode.jdk.proxy
- 1.1.6 目标类接口
- 1.1.7 目标类
- 1.1.8 代理类处理器
- 1.1.9 测试类
- 1.1.10 测试结果
- 1.1.11 生成的代理类源码
- 1.1.12 JDK动态代理的不足
1.1JDK动态代理
1.1.1 proxy
该类提供了方法创建代理类和代理类的对象的方法
创建一个代理类并返回代理类对象
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
loader : 类加载器,指定类加载器,是为了精确的定位类
interfaces : 接口Class类,使用JDK的反射,必须要有接口
h :InvocationHandler ,代理的处理器,每个代理类都有一个关联的处理器
1.1.2 InvocationHandler
是每个代理类对应的处理器
Object 方法调用的返回值,可以作为被代理的方法调用的返回值
proxy : 代理类对象
method : 目标类中被代理的方法
args : 目标类中被代理的方法的运行参数
Object invoke(Object proxy,Method method,Object[] args)
1.1.3 创建一个Maven项目
1.1.4 导入Spring的相关依赖
dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
1.1.5 修改包名为com.bjpowernode.jdk.proxy
1.1.6 目标类接口
package com.bjpowernode.jdk.proxy;
/**
* 目标接口类
*/
public interface ITargetClass {
/**
* 房子出租
* @param m
*/
void rent(int m);
}
1.1.7 目标类
package com.bjpowernode.jdk.proxy;
/**
* 目标类
*/
public class TargetClass implements ITargetClass{
@Override
public void rent(int m) {
System.out.println("出租的金额为:"+m);
}
}
1.1.8 代理类处理器
package com.bjpowernode.jdk.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 代理的处理器
* 处理器会被绑定一个代理
* 帮助代理调用目标方法
*/
public class MyInvocationHandler implements InvocationHandler {
/**
* 目标方法类的对象
*/
private Object targetObj;
public MyInvocationHandler(Object targetObj){
this.targetObj = targetObj;
}
/**
*
* @param proxy 生成的代理类的对象
* @param method 目标类中被代理的方法
* @param args 目标类中被代理的方法的实际参数
* @return 可以当做目标方法的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//使用反射调用 目标类中的方法
Object obj = method.invoke(targetObj, args);
return obj;
}
}
1.1.9 测试类
package com.bjpowernode.jdk.proxy;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
//创建了目标对象
ITargetClass targetClass =new TargetClass();
//创建处理器
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(targetClass);
//创建具体的代理类和对象 具体产生的代理类 会实现接口 所以能转化为接口类型
ITargetClass proxy = (ITargetClass)Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{ITargetClass.class}, myInvocationHandler);
//调用代理类中 rent 方法
proxy.rent(100);
}
}
1.1.10 测试结果
1.1.11 生成的代理类源码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.sun.proxy;
import com.bjpowernode.jdk.proxy.ITargetClass;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements ITargetClass {
private static Method m1;
private static Method m2;
private static Method m3;
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 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 void rent(int var1) throws {
try {
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
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"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.bjpowernode.jdk.proxy.ITargetClass").getMethod("rent", Integer.TYPE);
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
1.1.12 JDK动态代理的不足
在JDK中使用动态代理,必须有类的接口。因为生成的代理需要实现这个接口,这样我们生成的代理类对象,才能转化为代理目标的接口对象,然后根据接口中的方法,调用处理器中invoke方法。