spring创建的动态代理类
2025-07-07 本文已影响0人
zzz_0427
1、spring创建的动态代理类在哪里
Spring框架在运行时,通过动态字节码框架,在JVM创建的,运行在JVM内部,等程序结束后,会和JVM一起消失
动态字节码框架是一种基于Java字节码操作的技术,它允许在运行时对已编译的.class文件进行解析、修改或生成新的字节码。
动态字节码框架有ASM,javaassist,cglib
结论:动态代理不需要创建代理类文件,都是在JVM运行过程中动态创建,所以不会造成静态代理类过多。
spring创建动态代理的创建方式:
1、jdk的动态代理(是通过反射实现的)
2、cglib动态代理
代理创建的三要素:①目标对象,②额外功能,③和目标对象实现相同的接口
//jdk动态代理实现
import com.itbd.springai.service.UserService;
import com.itbd.springai.service.impl.UserServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserServiceProxy {
//①目标对象
private UserService userService = new UserServiceImpl();
public UserService proxy(){
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("---log---");
Object invoke = method.invoke(userService, args);
return invoke;
}
};
//public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
//②InvocationHandler实现额外的功能
//③interfaces实现相同的接口
return (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), invocationHandler);
}
public static void main(String[] args) {
System.out.println(System.getProperty("user.dir"));
//保存生成代理类文件
System.setProperty("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");
UserService proxy = new UserServiceProxy().proxy();
proxy.login("wjw","123456");
}
}
ClassLoader 借用其他类的类加载器,把下面生代理类的.class加载到jvm中,创建代理类Proxy0对象
生成的代理类.class文件
代理类文件
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package jdk.proxy1;
import com.itbd.springai.service.UserService;
import java.lang.invoke.MethodHandles;
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 UserService {
private static final Method m0;
private static final Method m1;
private static final Method m2;
private static final Method m3;
public $Proxy0(InvocationHandler var1) {
super(var1);
}
public final int hashCode() {
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 boolean equals(Object var1) {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() {
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 login(String var1, String var2) {
try {
super.h.invoke(this, m3, new Object[]{var1, var2});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
static {
try {
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
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.itbd.springai.service.UserService").getMethod("login", Class.forName("java.lang.String"), Class.forName("java.lang.String"));
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(((Throwable)var2).getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(((Throwable)var3).getMessage());
}
}
private static MethodHandles.Lookup proxyClassLookup(MethodHandles.Lookup var0) throws IllegalAccessException {
if (var0.lookupClass() == Proxy.class && var0.hasFullPrivilegeAccess()) {
return MethodHandles.lookup();
} else {
throw new IllegalAccessException(var0.toString());
}
}
}