java中的动态代理
java中的动态代理
java动态代理,我理解就是通过jvm本身,去生成class的字节码,生成的class文件是通过集成proxy,实现传入的接口来调用执行
InvocationHandler
里的方法.
先建立一个接口
package com.blaaair.proxy;
public interface UserInterface {
void query();
void select();
}
实现类
package com.blaaair.proxy;
public class UserImpl implements UserInterface {
public void query() {
System.out.println("query");
}
public void select() {
System.out.println("select");
}
}
InvocationHandler
package com.blaaair.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private UserImpl user;
public MyInvocationHandler(UserImpl user) {
this.user = user;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("-----before----");
Object invoke = method.invoke(user);
System.out.println("----after----");
return invoke;
}
}
Main
package com.blaaair.proxy;
import sun.misc.ProxyGenerator;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
// 生成代理类
UserInterface proxy = (UserInterface) Proxy.newProxyInstance(
Main.class.getClassLoader(), UserImpl.class.getInterfaces(),
new MyInvocationHandler(new UserImpl()));
proxy.query();
proxy.select();
//利用java反射提供的生成器获取到class字节
byte[] tests = ProxyGenerator.generateProxyClass("test", UserImpl.class.getInterfaces());
try {
// 输出到文件
OutputStream outputStream = new FileOutputStream(new File("D://test.class"));
outputStream.write(tests);
outputStream.flush();
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 利用classLoader读取到动态代理的class,通过class创建代理对象
try {
Class<?> test = Main.class.getClassLoader().loadClass("test");
Constructor<?> constructor = test.getConstructor(InvocationHandler.class);
UserInterface proxy2 = (UserInterface) constructor.newInstance(new MyInvocationHandler(new UserImpl()));
proxy2.query();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
查看生成的class结构
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import com.blaaair.proxy.UserInterface;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class test extends Proxy implements UserInterface {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m4;
private static Method m0;
public test(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 void query() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
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 select() throws {
try {
super.h.invoke(this, m4, (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);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("com.blaaair.proxy.UserInterface").getMethod("query");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m4 = Class.forName("com.blaaair.proxy.UserInterface").getMethod("select");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
解释
- public test(InvocationHandler var1) throws : 构造器传入InvocationHandler
- test extends Proxy implements
UserInterface
: 这点就可以说为什么jdk动态代理必须有接口 - super.h.invoke(this, m4, (Object[])null); : 从这就会调用到
InvocationHandler
的invoke方法,也就是说明什么? 执行自己实现InvocationHandler
的类中invoke方法!!!
java中的动态代理
https://www.blaaair.com/archives/java%E4%B8%AD%E7%9A%84%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86