动态代理
静态代理
- 创建一个接口,然后创建目标类实现该接口并且实现该接口中的抽象方法。之后再创建一个代理类,同时使其也实现这个接口。在代理类中持有一个目标对象的引用,而后在代理类方法中调用该对象的方法
动态代理
- 利用反射机制在运行时动态创建代理类
- JDK动态代理使用步骤
- 创建被代理的接口和类
- 创建InvocationHandler接口的实现类,重写invoke方法,在invoke方法中实现代理逻辑
- 通过Proxy的静态方法newProxyInstance( ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理对象
- ClassLoaderloader 在哪个类里创建代理对象,就传入该类的类加载器
- Class[] interfaces 代理类需要实现的接口
- InvocationHandler 代理逻辑对象
- 使用代理对象
实现原理
- 在Proxy.newProxyInstanceProxy方法内部,会调用Generator类的generateProxyClass()方法来生成代理类的字节码,需要传入参数:代理类需要实现的接口数组
- generateProxyClass()方法根据传入的接口数组,动态的成Class文件,包括字段和方法
- JDK动态代理产生的代理类【继承】Proxy类,java是单继承,jdk动态代理是以实现接口的方式来执行的,并且【实现】接口数组中所有的接口
- 代理类只有唯一构造方法,参数是InvocationHandlerd对象;构造方法内部逻辑是,把InvocationHandler对象传给父类Proxy类,也就是把InvocationHandler对象注入到Proxy类当中
- 在创建InvocationHandlerd对象的时候,我们可以选择把目标对象注入到了InvocationHandler对象中(目标对象注入到InvocationHandler中,InvocationHandler对象注入到Proxy中)
- 在使用代理类时,执行相应方法时,代理对象调用的是父类(Proxy类)中InvocationHandler对象的invoke方法,也就是我们之前重写的invoke方法:代理逻辑在此方法内
- 在InvocationHandler对象的invoke方法内,除了代理逻辑,还可以调用目标对象的方法(在创建InvocationHandler对象时,目标对象注入到了InvocationHandler中)
示例demo
- 目标接口
package Proxy;
public interface UserService {
public String getName(String userId);
}
- 目标实现类
package Proxy;
public class UserServiceImpl implements UserService{
@Override
public String getName(String userId) {
System.out.println("hello");
return userId;
}
}
- InvocationHandler实现类
package Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
class MyInvocationHandler implements InvocationHandler {
private Object object; //目标对象
//通过构造方法,把目标对象进入进来
public MyInvocationHandler(Object object){
this.object = object;
}
//代理逻辑
/***
* @param proxy 生成的代理对象
* @param method 代理对象中要执行的方法
* @param args 方法参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置代理逻辑");
Object object = method.invoke(this.object, args);//除了代理逻辑,还可以选择调用目标对象的方法;this.object为注入的目标对象
System.out.println("后置代理逻辑");
return object;
}
}
- main方法测试
public class ZhuydProxy {
public static void main(String[] args) throws IOException {
UserService target = new UserServiceImpl(); //创建目标对象
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(target); //创建代理逻辑对象,目标对象注入到InvocationHandler中
UserService userService = (UserService) Proxy.newProxyInstance(ZhuydProxy.class.getClassLoader(),
target.getClass().getInterfaces(),
myInvocationHandler
);//通过JDK动态代理,创建代理对象
userService.getName("123");//运用代理对象
}
- 运行结果
前置代理逻辑
hello
后置代理逻辑
查看动态代理生成的字节码文件到底张什么样
- 通过ProxyGenerator.generateProxyClass( 生成的代理类名字 , 代理接口数组 ) 方法生成:代理字节码文件
- 执行以下代码
byte[] bytes = ProxyGenerator.generateProxyClass("UserService$proxy",new Class[]{UserService.class});
Path path = new File("C:\\UserService$proxy.class").toPath();
Files.write(path,bytes);
- 生成的字节码文件
import Proxy.UserService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class UserService$proxy extends Proxy implements UserService {
private static Method m1;
private static Method m2;
private static Method m0;
private static Method m3;
public UserService$proxy(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 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);
}
}
public final String getName(String var1) throws {
try {
return (String)super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m3 = Class.forName("Proxy.UserService").getMethod("getName", Class.forName("java.lang.String"));
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
原创,如需转载请标明出处