Spring Festival is coming soon. I have nothing to do now. I took time to sort out Spring source code. Two days ago, I sorted out the Ioc of Spring, and then I started Aop. See can more arrive which more arrive which, not regular update ~~~~ anyway also have no one to see
In preparation for this installment, take a look at JDK dynamic proxies and Cglib. You still can’t figure it out. Cut me.
JDK dynamic proxy
The test code
public interface Test1 {
void sayHello(a);
}
public interface Test2 {
void sayBye(a);
}
public class TargetInterfaceImpl implements Test1.Test2{
@Override
public void sayHello(a) {
System.out.println("sayHello");
}
@Override
public void sayBye(a) {
System.out.println("sayBye"); }}public class JdkInvocation {
public static void main(String[] args) {
// The object to be proxied
Test1 t=new TargetInterfaceImpl();
// Custom Invocation implementation
InvocationHandler invokeHandler= (proxy, method, args1) -> {
method.invoke(t, args1);
return null; }; Test1 targetInterface=(Test1)Proxy.newProxyInstance(JdkInvocation.class.getClassLoader(),TargetInterfaceImpl.class.getInterfac es(),invokeHandler); targetInterface.sayHello();byte[] bytes = ProxyGenerator.generateProxyClass("aaaaa".new Class[]{targetInterface.getClass()});
try(
FileOutputStream fos =new FileOutputStream(new File("jdk.class"))
){
fos.write(bytes);
fos.flush();
}catch(Exception e){ e.printStackTrace(); }}}Copy the code
Source code analysis
The JDK dynamic Proxy basically implements the InvocationHandler, overrides the Invoke method, and gives proxy.newProxyInstance a Proxy object. ProxyGenerator. GenerateProxyClass for bytecode file and print, the following can be ignored. The main analysis is the Proxy newProxyInstance.
Class
cl = getProxyClass0(loader, intfs); The core is this step, generating a class, and then creating the object through reflection, so we just need to worry about getProxyClass0
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader, Class
[] interfaces, InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
finalClass<? >[] intfs = interfaces.clone();final SecurityManager sm = System.getSecurityManager();
if(sm ! =null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/* * Look up or generate the designated proxy class. */Class<? > cl = getProxyClass0(loader, intfs);/* * Invoke its constructor with the designated invocation handler. */
try {
if(sm ! =null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
finalConstructor<? > cons = cl.getConstructor(constructorParams);final InvocationHandler ih = h;
if(! Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run(a) {
cons.setAccessible(true);
return null; }}); }return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw newInternalError(t.toString(), t); }}catch (NoSuchMethodException e) {
throw newInternalError(e.toString(), e); }}Copy the code
Will eventually into Java. Lang. Reflect. Proxy. ProxyClassFactory# apply generated Proxy class, defineClass0 for native method, cannot follow up.
@Override public Class<? > apply(ClassLoader loader, Class<? >[] interfaces) { ... Slightly / * * Choose a name for the proxy class to generate the. * / long num = nextUniqueNumber. GetAndIncrement (); String proxyName = proxyPkg + proxyClassNamePrefix + num; /* * Generate the specified proxy class. */ byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try { return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); } catch (ClassFormatError e) { /* * A ClassFormatError here means that (barring bugs in the * proxy class generation code) there was some other * invalid aspect of the arguments supplied to the proxy * class creation (such as virtual machine limitations * exceeded). */ throw new IllegalArgumentException(e.toString()); }}Copy the code
And then we go to the outermost layer and we see something fishy, and we can see from the code that it has a constructor that needs to be passed in our InvocationHandler, ok
So JDK dynamic proxy is through the target interface, bytecode generation by JDK bottom layer, and then through their own implementation of the InvocationHandler specific execution. This is the JDK dynamic proxy.
importcom.sun.proxy.. Proxy0;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class aaaaa extends Proxy implements Proxy0 {
private static Method m1;
private static Method m8;
private static Method m2;
private static Method m7;
private static Method m12;
private static Method m14;
private static Method m0;
private static Method m11;
private static Method m3;
private static Method m13;
private static Method m5;
private static Method m10;
private static Method m6;
private static Method m4;
private static Method m9;
public aaaaa(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 newUndeclaredThrowableException(var4); }}public final InvocationHandler getInvocationHandler(Object var1) throws IllegalArgumentException {
try {
return (InvocationHandler)super.h.invoke(this, m8, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw newUndeclaredThrowableException(var4); }}public final String toString(a) throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final Class getProxyClass(ClassLoader var1, Class[] var2) throws IllegalArgumentException {
try {
return (Class)super.h.invoke(this, m7, new Object[]{var1, var2});
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw newUndeclaredThrowableException(var5); }}public final Class getClass(a) throws {
try {
return (Class)super.h.invoke(this, m12, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void notifyAll(a) throws {
try {
super.h.invoke(this, m14, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final int hashCode(a) throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void wait(a) throws InterruptedException {
try {
super.h.invoke(this, m11, (Object[])null);
} catch (RuntimeException | InterruptedException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void sayHello(a) throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void notify(a) throws {
try {
super.h.invoke(this, m13, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final Object newProxyInstance(ClassLoader var1, Class[] var2, InvocationHandler var3) throws IllegalArgumentException {
try {
return (Object)super.h.invoke(this, m5, new Object[]{var1, var2, var3});
} catch (RuntimeException | Error var5) {
throw var5;
} catch (Throwable var6) {
throw newUndeclaredThrowableException(var6); }}public final void wait(long var1) throws InterruptedException {
try {
super.h.invoke(this, m10, new Object[]{var1});
} catch (RuntimeException | InterruptedException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw newUndeclaredThrowableException(var5); }}public final boolean isProxyClass(Class var1) throws {
try {
return (Boolean)super.h.invoke(this, m6, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw newUndeclaredThrowableException(var4); }}public final void sayBye(a) throws {
try {
super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void wait(long var1, int var3) throws InterruptedException {
try {
super.h.invoke(this, m9, new Object[]{var1, var3});
} catch (RuntimeException | InterruptedException | Error var5) {
throw var5;
} catch (Throwable var6) {
throw newUndeclaredThrowableException(var6); }}static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m8 = Class.forName("com.sun.proxy.$Proxy0").getMethod("getInvocationHandler", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m7 = Class.forName("com.sun.proxy.$Proxy0").getMethod("getProxyClass", Class.forName("java.lang.ClassLoader"), Class.forName("[Ljava.lang.Class;"));
m12 = Class.forName("com.sun.proxy.$Proxy0").getMethod("getClass");
m14 = Class.forName("com.sun.proxy.$Proxy0").getMethod("notifyAll");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m11 = Class.forName("com.sun.proxy.$Proxy0").getMethod("wait");
m3 = Class.forName("com.sun.proxy.$Proxy0").getMethod("sayHello");
m13 = Class.forName("com.sun.proxy.$Proxy0").getMethod("notify");
m5 = Class.forName("com.sun.proxy.$Proxy0").getMethod("newProxyInstance", Class.forName("java.lang.ClassLoader"), Class.forName("[Ljava.lang.Class;"), Class.forName("java.lang.reflect.InvocationHandler"));
m10 = Class.forName("com.sun.proxy.$Proxy0").getMethod("wait", Long.TYPE);
m6 = Class.forName("com.sun.proxy.$Proxy0").getMethod("isProxyClass", Class.forName("java.lang.Class"));
m4 = Class.forName("com.sun.proxy.$Proxy0").getMethod("sayBye");
m9 = Class.forName("com.sun.proxy.$Proxy0").getMethod("wait", Long.TYPE, Integer.TYPE);
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw newNoClassDefFoundError(var3.getMessage()); }}}Copy the code
CGLIB
The test code
public class CglibOrigin {
public void sayHello(a){
System.out.println("hello world"); }}public class CglibCallBack implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Before call");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("After call"+result);
returnresult; }}public class Demo {
public static void main(String[] args) {
Enhancer enhancer =new Enhancer();
enhancer.setSuperclass(CglibOrigin.class);
enhancer.setCallback(new CglibCallBack());
CglibOrigin cglibTestOrigin=(CglibOrigin)enhancer.create();
cglibTestOrigin.sayHello();
byte[] bytes = ProxyGenerator.generateProxyClass("aaaa".new Class[]{cglibTestOrigin.getClass()});
try{
FileOutputStream fos =new FileOutputStream(new File("aaaa.class"));
fos.write(bytes);
fos.flush();
}catch(Exception e){ e.printStackTrace(); }}}Copy the code
Source code analysis
As you can see from the test code, cglib can generate proxy classes of classes without relying on interfaces, all of which are encapsulated in the CREATE method. So let’s just focus on the create method that eventually calls a Future to do the creation. I’m going to skip the middle step here and skip right to the creation.
Finally, the Enhancer calls the parent class for creation. So we skip the middle step and go straight to the researchnet.sf.cglib.core.AbstractClassGenerator#generate
. If you look at the code below, you can see that it is similar to the JDK dynamic proxy, which is created by bytecode and then reflection. So let’s take a look at generating bytecode
protected Class generate(ClassLoaderData data) {
Class gen;
Object save = CURRENT.get();
CURRENT.set(this);
try {
ClassLoader classLoader = data.getClassLoader();
if (classLoader == null) {
throw new IllegalStateException("ClassLoader is null while trying to define class " +
getClassName() + ". It seems that the loader has been expired from a weak reference somehow. " +
"Please file an issue at cglib's issue tracker.");
}
synchronized (classLoader) {
String name = generateClassName(data.getUniqueNamePredicate());
data.reserveName(name);
this.setClassName(name);
}
if (attemptLoad) {
try {
gen = classLoader.loadClass(getClassName());
return gen;
} catch (ClassNotFoundException e) {
// ignore}}byte[] b = strategy.generate(this);
// The following lines were added by myself for easy observation
String className = ClassNameReader.getClassName(new ClassReader(b));
try{
FileOutputStream fos =new FileOutputStream(new File(integer.incrementAndGet()+".class"));
fos.write(b);
fos.flush();
}catch (Exception e){
e.printStackTrace();
}
ProtectionDomain protectionDomain = getProtectionDomain();
synchronized (classLoader) { // just in case
if (protectionDomain == null) {
gen = ReflectUtils.defineClass(className, b, classLoader);
} else{ gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain); }}return gen;
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
} finally{ CURRENT.set(save); }}Copy the code
Its implementation is through the net. Sf. Additional, proxy. Enhancer# generateClass method, here will touch my knowledge blind area, additional incredibly handwritten bytecode, interested can study the ha (I have hair)
public void generateClass(ClassVisitor v) throws Exception {
Class sc = (superclass == null)? Object.class : superclass;if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException("Cannot subclass final class " + sc.getName());
List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
filterConstructors(sc, constructors);
// Order is very important: must add superclass, then
// its superclass chain, then each interface and
// its superinterfaces.
List actualMethods = new ArrayList();
List interfaceMethods = new ArrayList();
final Set forcePublic = new HashSet();
getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
List methods = CollectionUtils.transform(actualMethods, new Transformer() {
public Object transform(Object value) {
Method method = (Method)value;
int modifiers = Constants.ACC_FINAL
| (method.getModifiers()
& ~Constants.ACC_ABSTRACT
& ~Constants.ACC_NATIVE
& ~Constants.ACC_SYNCHRONIZED);
if (forcePublic.contains(MethodWrapper.create(method))) {
modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
}
returnReflectUtils.getMethodInfo(method, modifiers); }}); ClassEmitter e =new ClassEmitter(v);
if (currentData == null) {
e.begin_class(Constants.V1_8,
Constants.ACC_PUBLIC,
getClassName(),
Type.getType(sc),
(useFactory ?
TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) :
TypeUtils.getTypes(interfaces)),
Constants.SOURCE_FILE);
} else {
e.begin_class(Constants.V1_8,
Constants.ACC_PUBLIC,
getClassName(),
null.new Type[]{FACTORY},
Constants.SOURCE_FILE);
}
List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null);
e.declare_field(Constants.ACC_PUBLIC | Constants.ACC_STATIC, FACTORY_DATA_FIELD, OBJECT_TYPE, null);
if(! interceptDuringConstruction) { e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, Type.BOOLEAN_TYPE,null);
}
e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null);
e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null);
if(serialVersionUID ! =null) {
e.declare_field(Constants.PRIVATE_FINAL_STATIC, Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID);
}
for (int i = 0; i < callbackTypes.length; i++) {
e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null);
}
// This is declared private to avoid "public field" pollution
e.declare_field(Constants.ACC_PRIVATE | Constants.ACC_STATIC, CALLBACK_FILTER_FIELD, OBJECT_TYPE, null);
if (currentData == null) {
emitMethods(e, methods, actualMethods);
emitConstructors(e, constructorInfo);
} else {
emitDefaultConstructor(e);
}
emitSetThreadCallbacks(e);
emitSetStaticCallbacks(e);
emitBindCallbacks(e);
if(useFactory || currentData ! =null) {
int[] keys = getCallbackKeys();
emitNewInstanceCallbacks(e);
emitNewInstanceCallback(e);
emitNewInstanceMultiarg(e, constructorInfo);
emitGetCallback(e, keys);
emitSetCallback(e, keys);
emitGetCallbacks(e);
emitSetCallbacks(e);
}
e.end_class();
}
// Convert to a byte array
public byte[] toByteArray() {
return (byte[]) java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run(a) {
byte[] b = ((ClassWriter) DebuggingClassWriter.super.cv).toByteArray();
if(debugLocation ! =null) {
String dirs = className.replace('. ', File.separatorChar);
try {
new File(debugLocation + File.separatorChar + dirs).getParentFile().mkdirs();
File file = new File(new File(debugLocation), dirs + ".class");
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
try {
out.write(b);
} finally {
out.close();
}
if(traceCtor ! =null) {
file = new File(new File(debugLocation), dirs + ".asm");
out = new BufferedOutputStream(new FileOutputStream(file));
try {
ClassReader cr = new ClassReader(b);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
ClassVisitor tcv = (ClassVisitor)traceCtor.newInstance(new Object[]{null, pw});
cr.accept(tcv, 0);
pw.flush();
} finally{ out.close(); }}}catch (Exception e) {
throw newCodeGenerationException(e); }}returnb; }}); }Copy the code
Here’s a direct look at the generated bytecode, which is similar to JDK dynamic proxies, all done through the InvocationHandler. After all, you write bytecode by hand. It doesn’t matter how you write it. Here you go
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.MethodProxy;
importnet.sf.cglib.self.CglibOrigin.. EnhancerByCGLIB.. e61bfbb8;public final class aaaa extends Proxy implements e61bfbb8 {
private static Method m1;
private static Method m11;
private static Method m2;
private static Method m5;
private static Method m17;
private static Method m19;
private static Method m0;
private static Method m16;
private static Method m8;
private static Method m9;
private static Method m4;
private static Method m3;
private static Method m18;
private static Method m10;
private static Method m12;
private static Method m15;
private static Method m14;
private static Method m6;
private static Method m7;
private static Method m13;
public aaaa(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 newUndeclaredThrowableException(var4); }}public final Object newInstance(Callback[] var1) throws {
try {
return (Object)super.h.invoke(this, m11, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw newUndeclaredThrowableException(var4); }}public final String toString(a) throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final Callback getCallback(int var1) throws {
try {
return (Callback)super.h.invoke(this, m5, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw newUndeclaredThrowableException(var4); }}public final Class getClass(a) throws {
try {
return (Class)super.h.invoke(this, m17, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void notifyAll(a) throws {
try {
super.h.invoke(this, m19, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final int hashCode(a) throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void wait(a) throws InterruptedException {
try {
super.h.invoke(this, m16, (Object[])null);
} catch (RuntimeException | InterruptedException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void sayHello(a) throws {
try {
super.h.invoke(this, m8, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void CGLIB$SET_STATIC_CALLBACKS(Callback[] var1) throws {
try {
super.h.invoke(this, m9, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw newUndeclaredThrowableException(var4); }}public final void setCallbacks(Callback[] var1) throws {
try {
super.h.invoke(this, m4, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw newUndeclaredThrowableException(var4); }}public final void setCallback(int var1, Callback var2) throws {
try {
super.h.invoke(this, m3, new Object[]{var1, var2});
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw newUndeclaredThrowableException(var5); }}public final void notify(a) throws {
try {
super.h.invoke(this, m18, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final void CGLIB$SET_THREAD_CALLBACKS(Callback[] var1) throws {
try {
super.h.invoke(this, m10, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw newUndeclaredThrowableException(var4); }}public final Object newInstance(Class[] var1, Object[] var2, Callback[] var3) throws {
try {
return (Object)super.h.invoke(this, m12, new Object[]{var1, var2, var3});
} catch (RuntimeException | Error var5) {
throw var5;
} catch (Throwable var6) {
throw newUndeclaredThrowableException(var6); }}public final void wait(long var1) throws InterruptedException {
try {
super.h.invoke(this, m15, new Object[]{var1});
} catch (RuntimeException | InterruptedException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw newUndeclaredThrowableException(var5); }}public final void wait(long var1, int var3) throws InterruptedException {
try {
super.h.invoke(this, m14, new Object[]{var1, var3});
} catch (RuntimeException | InterruptedException | Error var5) {
throw var5;
} catch (Throwable var6) {
throw newUndeclaredThrowableException(var6); }}public final Callback[] getCallbacks() throws {
try {
return (Callback[])super.h.invoke(this, m6, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw newUndeclaredThrowableException(var3); }}public final MethodProxy CGLIB$findMethodProxy(Signature var1) throws {
try {
return (MethodProxy)super.h.invoke(this, m7, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw newUndeclaredThrowableException(var4); }}public final Object newInstance(Callback var1) throws {
try {
return (Object)super.h.invoke(this, m13, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw newUndeclaredThrowableException(var4); }}static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m11 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("newInstance", Class.forName("[Lnet.sf.cglib.proxy.Callback;"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m5 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("getCallback", Integer.TYPE);
m17 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("getClass");
m19 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("notifyAll");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m16 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("wait");
m8 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("sayHello");
m9 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("CGLIB$SET_STATIC_CALLBACKS", Class.forName("[Lnet.sf.cglib.proxy.Callback;"));
m4 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("setCallbacks", Class.forName("[Lnet.sf.cglib.proxy.Callback;"));
m3 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("setCallback", Integer.TYPE, Class.forName("net.sf.cglib.proxy.Callback"));
m18 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("notify");
m10 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("CGLIB$SET_THREAD_CALLBACKS", Class.forName("[Lnet.sf.cglib.proxy.Callback;"));
m12 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("newInstance", Class.forName("[Ljava.lang.Class;"), Class.forName("[Ljava.lang.Object;"), Class.forName("[Lnet.sf.cglib.proxy.Callback;"));
m15 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("wait", Long.TYPE);
m14 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("wait", Long.TYPE, Integer.TYPE);
m6 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("getCallbacks");
m7 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("CGLIB$findMethodProxy", Class.forName("net.sf.cglib.core.Signature"));
m13 = Class.forName("net.sf.cglib.self.CglibOrigin$$EnhancerByCGLIB$$e61bfbb8").getMethod("newInstance", Class.forName("net.sf.cglib.proxy.Callback"));
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw newNoClassDefFoundError(var3.getMessage()); }}}Copy the code
conclusion
- JDK dynamic proxy: need interface to create proxy objects, essentially by the underlying layer, create bytecode, directly generated objects, the actual call is their own implementation
InvocationHandler
- CGLIB: Generates its own bytecode according to the specification without an interface.
The last few days of the year ago, more free, so I sort out the Spring source code, will soon go back to the Spring Festival, the later update frequency will not be so fast, the AOP part will be updated. Behind may update the time completely depends on the mood + time, that group of volume king is how to achieve day more, even a day several more, I anyway wrote a few hours did not, true liver immobile. If you are interested, please contact me to discuss the technology together. (It is not easy to create, please give a thumbs up.)