public class Person {
public void sayHello() {
System.out.println("Hello!");
}
}
System.setProperty(
DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E://xiaobaidemo");
这行代码用来生成cglib生成的代理类,输出到指定目录
System.setProperty(
DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E://xiaobaidemo")
public class Test20221111 {
public static void main(String[] args) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E://xiaobaidemo");
Enhancer.create(Person.class, new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Intercept!");
methodProxy.invokeSuper(o, objects);
return null;
}
});
}
}
https://juejin.cn/post/6844904077877313549
public class Person$$EnhancerByCGLIB$$34b905e4
extends Person {
private boolean CGLIB$BOUND;
public static Object CGLIB$FACTORY_DATA;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static Object CGLIB$CALLBACK_FILTER;
private static final Method CGLIB$sayHello$0$Method;
private static final MethodProxy CGLIB$sayHello$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$equals$1$Method;
private static final MethodProxy CGLIB$equals$1$Proxy;
private static final Method CGLIB$toString$2$Method;
private static final MethodProxy CGLIB$toString$2$Proxy;
private static final Method CGLIB$hashCode$3$Method;
private static final MethodProxy CGLIB$hashCode$3$Proxy;
private static final Method CGLIB$clone$4$Method;
private static final MethodProxy CGLIB$clone$4$Proxy;
static void CGLIB$STATICHOOK2() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class class_ = Class.forName("Person$$EnhancerByCGLIB$$34b905e4");
Class class_2 = Class.forName("java.lang.Object");
Method[] arrmethod = ReflectUtils.findMethods((String[])new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (Method[])class_2.getDeclaredMethods());
CGLIB$equals$1$Method = arrmethod[0];
CGLIB$equals$1$Proxy = MethodProxy.create(class_2, class_, (String)"(Ljava/lang/Object;)Z", (String)"equals", (String)"CGLIB$equals$1");
CGLIB$toString$2$Method = arrmethod[1];
CGLIB$toString$2$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/String;", (String)"toString", (String)"CGLIB$toString$2");
CGLIB$hashCode$3$Method = arrmethod[2];
CGLIB$hashCode$3$Proxy = MethodProxy.create(class_2, class_, (String)"()I", (String)"hashCode", (String)"CGLIB$hashCode$3");
CGLIB$clone$4$Method = arrmethod[3];
CGLIB$clone$4$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/Object;", (String)"clone", (String)"CGLIB$clone$4");
class_2 = Class.forName("Person");
CGLIB$sayHello$0$Method = ReflectUtils.findMethods((String[])new String[]{"sayHello", "()V"}, (Method[])class_2.getDeclaredMethods())[0];
CGLIB$sayHello$0$Proxy = MethodProxy.create(class_2, class_, (String)"()V", (String)"sayHello", (String)"CGLIB$sayHello$0");
}
final void CGLIB$sayHello$0() {
super.sayHello();
}
public final void sayHello() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
Person$$EnhancerByCGLIB$$34b905e4.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object = methodInterceptor.intercept((Object)this, CGLIB$sayHello$0$Method, CGLIB$emptyArgs, CGLIB$sayHello$0$Proxy);
return;
}
super.sayHello();
}
final boolean CGLIB$equals$1(Object object) {
return super.equals(object);
}
public final boolean equals(Object object) {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
Person$$EnhancerByCGLIB$$34b905e4.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor == null) return super.equals(object);
Object object2 = methodInterceptor.intercept((Object)this, CGLIB$equals$1$Method, new Object[]{object}, CGLIB$equals$1$Proxy);
if (object2 == null) {
return false;
}
boolean bl = (Boolean)object2;
return bl;
}
final String CGLIB$toString$2() {
return super.toString();
}
public final String toString() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
Person$$EnhancerByCGLIB$$34b905e4.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor == null) return super.toString();
return (String)methodInterceptor.intercept((Object)this, CGLIB$toString$2$Method, CGLIB$emptyArgs, CGLIB$toString$2$Proxy);
}
final int CGLIB$hashCode$3() {
return super.hashCode();
}
public final int hashCode() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
Person$$EnhancerByCGLIB$$34b905e4.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor == null) return super.hashCode();
Object object = methodInterceptor.intercept((Object)this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy);
if (object == null) {
return 0;
}
int n = ((Number)object).intValue();
return n;
}
final Object CGLIB$clone$4() throws CloneNotSupportedException {
return super.clone();
}
protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
Person$$EnhancerByCGLIB$$34b905e4.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor == null) return super.clone();
return methodInterceptor.intercept((Object)this, CGLIB$clone$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy);
}
public static MethodProxy CGLIB$findMethodProxy(Signature signature) {
String string = signature.toString();
switch (string.hashCode()) {
case -508378822: {
if (!string.equals("clone()Ljava/lang/Object;")) return null;
return CGLIB$clone$4$Proxy;
}
case 1535311470: {
if (!string.equals("sayHello()V")) return null;
return CGLIB$sayHello$0$Proxy;
}
case 1826985398: {
if (!string.equals("equals(Ljava/lang/Object;)Z")) return null;
return CGLIB$equals$1$Proxy;
}
case 1913648695: {
if (!string.equals("toString()Ljava/lang/String;")) return null;
return CGLIB$toString$2$Proxy;
}
case 1984935277: {
if (!string.equals("hashCode()I")) return null;
return CGLIB$hashCode$3$Proxy;
}
}
return null;
}
public Person$$EnhancerByCGLIB$$34b905e4() {
Person$$EnhancerByCGLIB$$34b905e4 person$$EnhancerByCGLIB$$34b905e4 = this;
Person$$EnhancerByCGLIB$$34b905e4.CGLIB$BIND_CALLBACKS((Object)person$$EnhancerByCGLIB$$34b905e4);
}
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] arrcallback) {
CGLIB$THREAD_CALLBACKS.set(arrcallback);
}
public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] arrcallback) {
CGLIB$STATIC_CALLBACKS = arrcallback;
}
private static final void CGLIB$BIND_CALLBACKS(Object object) {
Person$$EnhancerByCGLIB$$34b905e4 person$$EnhancerByCGLIB$$34b905e4 = (Person$$EnhancerByCGLIB$$34b905e4)object;
if (person$$EnhancerByCGLIB$$34b905e4.CGLIB$BOUND) return;
person$$EnhancerByCGLIB$$34b905e4.CGLIB$BOUND = true;
Object t = CGLIB$THREAD_CALLBACKS.get();
if (t == null && (v783 = CGLIB$STATIC_CALLBACKS) == null) {
return;
}
person$$EnhancerByCGLIB$$34b905e4.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])t)[0];
}
static {
Person$$EnhancerByCGLIB$$34b905e4.CGLIB$STATICHOOK2();
}
}
在创建一个代理类的对象的时候,会先加载这个Cglib创建的代理类的静态方法CGLIB$STATICHOOK2()。这个函数中对类的其他静态字段进行了初始化。例如:对那个每个需要代理的方法都生成两个字段,一个用于反射的Method对象,另一个用于加快方法调用,避免反射带来的开销的MethodProxy对象。然后在构造函数里面调用了GCLIB$BIND_CALLBACKS(this),在CGLIB$BIND_CALLBACKS方法中会把private MethodInterceptor CGLIB$CALLBACK_0字段和设置的静态变量ThreadLocal CGLIB$THREAD_CALLBACKS进行绑定,也就是说,设置的Callback并不是硬编码在生成代理类里面的,而是可以动态的设置。
由于代理类继承了被代理类,所以调用sayHello()方法时会直接调用代理类的sayHello()方法,而在代理类的方法中,调用了Callback的逻辑。
MethodInterceptor的interceptor方法参数:
if (methodInterceptor != null) {
Object object = methodInterceptor.intercept((Object)this, CGLIB$sayHello$0$Method, CGLIB$emptyArgs, CGLIB$sayHello$0$Proxy);
return;
}
①代理对象
②目标类的方法 CGLIB$sayHello$0$Method。通过目标类反射获取的方法
③方法参数
④目标类的代理方法CGLIB$sayHello$0$Proxy
MethodProxy是cglib包中提供的一个类。
package org.springframework.cglib.proxy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.springframework.cglib.core.AbstractClassGenerator;
import org.springframework.cglib.core.CodeGenerationException;
import org.springframework.cglib.core.GeneratorStrategy;
import org.springframework.cglib.core.NamingPolicy;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.reflect.FastClass;
/**
* Classes generated by {@link Enhancer} pass this object to the
* registered {@link MethodInterceptor} objects when an intercepted method is invoked. It can
* be used to either invoke the original method, or call the same method on a different
* object of the same type.
* @version $Id: MethodProxy.java,v 1.16 2009/01/11 20:09:48 herbyderby Exp $
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class MethodProxy {
private Signature sig1;
private Signature sig2;
private CreateInfo createInfo;
private final Object initLock = new Object();
private volatile FastClassInfo fastClassInfo;
/**
* For internal use by {@link Enhancer} only; see the {@link org.springframework.cglib.reflect.FastMethod} class
* for similar functionality.
* 看这里。看这里。看这里。create方法构建一个MethodProxy对象。
* ① Class c1 是目标对象的Class
* ② Class c2 是代理对象的Class
* ③ desc 是否方法描述
* ④ name1 是目标对象的方法名
* ⑤ name2 是代理对象的方法名
*/
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
MethodProxy proxy = new MethodProxy();
proxy.sig1 = new Signature(name1, desc);
proxy.sig2 = new Signature(name2, desc);
proxy.createInfo = new CreateInfo(c1, c2);
return proxy;
}
private void init() {
/*
* Using a volatile invariant allows us to initialize the FastClass and
* method index pairs atomically.
*
* Double-checked locking is safe with volatile in Java 5. Before 1.5 this
* code could allow fastClassInfo to be instantiated more than once, which
* appears to be benign.
*/
if (fastClassInfo == null) {
synchronized (initLock) {
if (fastClassInfo == null) {
CreateInfo ci = createInfo;
FastClassInfo fci = new FastClassInfo();
fci.f1 = helper(ci, ci.c1);
fci.f2 = helper(ci, ci.c2);
fci.i1 = fci.f1.getIndex(sig1);
fci.i2 = fci.f2.getIndex(sig2);
fastClassInfo = fci;
createInfo = null;
}
}
}
}
private static class FastClassInfo {
FastClass f1;
FastClass f2;
int i1;
int i2;
}
private static class CreateInfo {
Class c1;
Class c2;
NamingPolicy namingPolicy;
GeneratorStrategy strategy;
boolean attemptLoad;
public CreateInfo(Class c1, Class c2) {
this.c1 = c1;
this.c2 = c2;
AbstractClassGenerator fromEnhancer = AbstractClassGenerator.getCurrent();
if (fromEnhancer != null) {
namingPolicy = fromEnhancer.getNamingPolicy();
strategy = fromEnhancer.getStrategy();
attemptLoad = fromEnhancer.getAttemptLoad();
}
}
}
private static FastClass helper(CreateInfo ci, Class type) {
FastClass.Generator g = new FastClass.Generator();
g.setType(type);
// SPRING PATCH BEGIN
g.setContextClass(type);
// SPRING PATCH END
g.setClassLoader(ci.c2.getClassLoader());
g.setNamingPolicy(ci.namingPolicy);
g.setStrategy(ci.strategy);
g.setAttemptLoad(ci.attemptLoad);
return g.create();
}
private MethodProxy() {
}
/**
* Return the signature of the proxied method.
*/
public Signature getSignature() {
return sig1;
}
/**
* Return the name of the synthetic method created by CGLIB which is
* used by {@link #invokeSuper} to invoke the superclass
* (non-intercepted) method implementation. The parameter types are
* the same as the proxied method.
*/
public String getSuperName() {
return sig2.getName();
}
/**
* Return the {@link org.springframework.cglib.reflect.FastClass} method index
* for the method used by {@link #invokeSuper}. This index uniquely
* identifies the method within the generated proxy, and therefore
* can be useful to reference external metadata.
* @see #getSuperName
*/
public int getSuperIndex() {
init();
return fastClassInfo.i2;
}
// For testing
FastClass getFastClass() {
init();
return fastClassInfo.f1;
}
// For testing
FastClass getSuperFastClass() {
init();
return fastClassInfo.f2;
}
/**
* Return the MethodProxy used when intercepting the method
* matching the given signature.
* @param type the class generated by Enhancer
* @param sig the signature to match
* @return the MethodProxy instance, or null if no applicable matching method is found
* @throws IllegalArgumentException if the Class was not created by Enhancer or does not use a MethodInterceptor
*/
public static MethodProxy find(Class type, Signature sig) {
try {
Method m = type.getDeclaredMethod(MethodInterceptorGenerator.FIND_PROXY_NAME,
MethodInterceptorGenerator.FIND_PROXY_TYPES);
return (MethodProxy) m.invoke(null, new Object[]{sig});
}
catch (NoSuchMethodException ex) {
throw new IllegalArgumentException("Class " + type + " does not use a MethodInterceptor");
}
catch (IllegalAccessException | InvocationTargetException ex) {
throw new CodeGenerationException(ex);
}
}
/**
* Invoke the original method, on a different object of the same type.
* @param obj the compatible object; recursion will result if you use the object passed as the first
* argument to the MethodInterceptor (usually not what you want)
* @param args the arguments passed to the intercepted method; you may substitute a different
* argument array as long as the types are compatible
* @throws Throwable the bare exceptions thrown by the called method are passed through
* without wrapping in an InvocationTargetException
* @see MethodInterceptor#intercept
*/
public Object invoke(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f1.invoke(fci.i1, obj, args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
if (fastClassInfo.i1 < 0)
throw new IllegalArgumentException("Protected method: " + sig1);
throw ex;
}
}
/**
* Invoke the original (super) method on the specified object.
* @param obj the enhanced object, must be the object passed as the first
* argument to the MethodInterceptor
* @param args the arguments passed to the intercepted method; you may substitute a different
* argument array as long as the types are compatible
* @throws Throwable the bare exceptions thrown by the called method are passed through
* without wrapping in an InvocationTargetException
* @see MethodInterceptor#intercept
* 看这里,看这里,看这里
* 当调用methodProxy的invokeSuper方法的时候。传入的是代理对象obj,方法参数args。
* ①首先调用init方法。
* ②构建FastClassInfo对象,FastClassInfo对象的成员变量赋值。f1是目标对象的FastClass对象,f2是代理对象的FastClass对象。注意:FastClassInfo和FastClass对象是不一样的。
* ③ FastClassInfo对象设置属性i1 = 目标对象方法的索引。i2 = 代理对象方法的索引
* ④ 设置methodProxy的变量fastClassInfo = 创建的fastClassInfo对象
* ⑤ 调用f2对象的fastClass对象的invoke方法。传入方法的坐标,代理对象,方法参数。
* (1) fci.f2 = 代理对象的fastClass对象。调用代理对象的fastClass的invoke方法。
* (2) invoke方法参数中fci.i2表示的是代理对象方法的索引。比如上文中sayHello(目标对象的方法),CGLIB$sayHello$0(代理对象的方法)。这里执行的是代理对象的方法。obj是代理对象,args是方法参数。
* (3)根据索引找到匹配的方法,直接执行obj对象的方法。
*/
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
}
java反射调用方法是比较“重”的操作,要经过一系列的权限验证、通过native方法请求jvm去方法区查找方法定义、以及最后的invoke仍然可能要通过JNI调用native方法。而相比之下,FastClass方式则跟一般的一个普通的对象方法调用没啥区别、只是多了一步根据index判断调用委托类的哪个方法这一步骤、性能损耗基本没有。
cglib的大概逻辑如下:
(1)ASM构建代理类。继承目标类。代理类实例化过程:
①调用静态代码块,调用静态方法,对类中静态属性赋值。关键点是。对目标类中的所有方法,生成两个变量,一个Method,表示目标类方法。一个MethodProxy,表示通过MethodProxy构建的methodProxy。
②MethodProxy里面的fastClassInfo属性,保存了代理类fastClass,目标类fastClass,代理类方法索引,目标类方法索引。
③方法拦截中执行MethodProxy的invokeSupper方法,里面通过fastClassInfo获取代理类的fastClass类,然后调用fastClass的invoke方法。
④fastclass的invoke方法根据传入的方法索引,直接对象的方法。
fastClass机制

综上可以看出,FastClass调用invoke,其实就是将Object转换为目标类或者代理类。根据索引,直接调用对象的相关方法。
(1)MethodProxy.invoke。调用的是目标对象的方法,多态特性,调用的还是代理类中的sayHello方法,接着还会去调用拦截方法,拦截方法中调用MethodProxy.invoke,接着调用代理类的sayHello方法…陷入死循环。
public final void sayHello() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
Person$$EnhancerByCGLIB$$34b905e4.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
// 被代理方法(methodProxy.invoke会调用)
Object object = methodInterceptor.intercept((Object)this, CGLIB$sayHello$0$Method, CGLIB$emptyArgs, CGLIB$sayHello$0$Proxy);
return;
}
super.sayHello();
}
(2)MethodProxy.invokeSuper。调用的是代理对象中的代理方法(CGLIB$sayHello$0),调用的是目标类中的sayHello方法。
final void CGLIB$sayHello$0() {
super.sayHello();
}
先了解一个概念:FastClass机制。Cglib动态代理方法效率之所以比Jdk的高。就是因为Cglib采用了FastClass机制。
FastClass机制:为代理类和目标类各生成一个Class,这个Class会为代理类或目标类的方法分配一个index(int类型)。这个index当做一个入参,FastClass就可以直接定位要调用的方法直接进行调用,这样省去了反射调用,所以调用效率比jdk动态代理通过反射调用高。
FastClass反编译:
//根据方法签名获取index
public int getIndex(Signature var1) {
String var10000 = var1.toString();
switch(var10000.hashCode()) {
case -2077043409:
if(var10000.equals("getPerson(Ljava/lang/String;)Lcom/demo/pojo/Person;")) {
return 21;
}
break;
case -2055565910:
if(var10000.equals("CGLIB$SET_THREAD_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V")) {
return 12;
}
break;
case -1902447170:
if(var10000.equals("setPerson()V")) {
return 7;
}
break;
//省略部分代码.....
//根据index直接定位执行方法
public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
eaaaed75 var10000 = (eaaaed75)var2;
int var10001 = var1;
try {
switch(var10001) {
case 0:
return new Boolean(var10000.equals(var3[0]));
case 1:
return var10000.toString();
case 2:
return new Integer(var10000.hashCode());
case 3:
return var10000.newInstance((Class[])var3[0], (Object[])var3[1], (Callback[])var3[2]);
case 4:
return var10000.newInstance((Callback)var3[0]);
case 5:
return var10000.newInstance((Callback[])var3[0]);
case 6:
var10000.setCallback(((Number)var3[0]).intValue(), (Callback)var3[1]);
return null;
case 7:
var10000.setPerson();
return null;
case 8:
var10000.setCallbacks((Callback[])var3[0]);
return null;
case 9:
return var10000.getCallback(((Number)var3[0]).intValue());
case 10:
return var10000.getCallbacks();
case 11:
eaaaed75.CGLIB$SET_STATIC_CALLBACKS((Callback[])var3[0]);
return null;
case 12:
eaaaed75.CGLIB$SET_THREAD_CALLBACKS((Callback[])var3[0]);
return null;
case 13:
return eaaaed75.CGLIB$findMethodProxy((Signature)var3[0]);
case 14:
return var10000.CGLIB$toString$3();
case 15:
return new Boolean(var10000.CGLIB$equals$2(var3[0]));
case 16:
return var10000.CGLIB$clone$5();
case 17:
return new Integer(var10000.CGLIB$hashCode$4());
case 18:
var10000.CGLIB$finalize$1();
return null;
case 19:
var10000.CGLIB$setPerson$0();
return null;
//省略部分代码....
} catch (Throwable var4) {
throw new InvocationTargetException(var4);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
FastClass并不是跟代理类一块生成的,而是在第一次执行MethodProxy的invoke/invokeSuper时生成并放在缓存中。
private void init() {
if(this.fastClassInfo == null) {
Object var1 = this.initLock;
synchronized(this.initLock) {
if(this.fastClassInfo == null) {
MethodProxy.CreateInfo ci = this.createInfo;
MethodProxy.FastClassInfo fci = new MethodProxy.FastClassInfo();
fci.f1 = helper(ci, ci.c1);//如果缓存中就取出,没有就生成新的FastClass
fci.f2 = helper(ci, ci.c2);
fci.i1 = fci.f1.getIndex(this.sig1);//获取方法的index
fci.i2 = fci.f2.getIndex(this.sig2);
this.fastClassInfo = fci;
this.createInfo = null;
}
}
}
}
public interface HelloService {
void sayHello();
}
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello(){
System.out.println(”hello Word“);
}
}
public class HelloServiceImplHandle implements InvocationHandler{
private Object target;
public HelloServiceImplHandle(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("proxy before=======");
Object result = method.invoke(target, args);
System.out.println("proxy end=======");
return result;
}
}
HelloService helloService = new HelloServiceImplHandle();
HelloServiceImplHandle helloServiceImplHandle = new HelloServiceImplHandle();
Proxy.newProxyInstance(helloService .getClass().getClassLoad(),helloService .getClass().getInterfaces(),helloServiceImplHandle )
public final class $Proxy0 extends Proxy implements HelloService {
private static Method m1; //equals()方法
private static Method m3; //我们的sayHello方法()
private static Method m2; //toString()方法
private static Method m0; //hashCode()方法
//这里就是我们之前提交的InvocationHandler这个构造方法!!
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})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
//看一看我们的代理类的sayHello()方法长什么样子呀!!
public final void sayHello() 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 int hashCode() throws {
try {
return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
m3 = Class.forName("proxy.service.HelloService").getMethod("sayHello", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
代理类继承Proxy类,Proxy类里面保存了我们定义的InvocationHandler的实现。
public class Proxy implements java.io.Serializable {
private static final long serialVersionUID = -2222568056686623797L;
// 这个就是我们定义的InvocationHandler 的实现
protected InvocationHandler h;
private Proxy() {
}
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
// 我们构建代理对象的方法。这里面将InvocationHandler 进行赋值。
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class>[] 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);
}
final Constructor> cons = cl.getConstructor(constructorParams);
// 在这里进行赋值增强的逻辑
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
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 new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
@CallerSensitive
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
{
/*
* Verify that the object is actually a proxy instance.
*/
if (!isProxyClass(proxy.getClass())) {
throw new IllegalArgumentException("not a proxy instance");
}
final Proxy p = (Proxy) proxy;
final InvocationHandler ih = p.h;
if (System.getSecurityManager() != null) {
Class> ihClass = ih.getClass();
Class> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
ihClass.getClassLoader()))
{
ReflectUtil.checkPackageAccess(ihClass);
}
}
return ih;
}
}
代理类实例化,首先调用静态代码块。通过反射,获取Object,目标类的Method。赋值给代理类的静态属性。
代理对象方法的调用。如下。逻辑很清晰,调用:Proxy的h(InvocationHandler的实现类)的invoke方法。
invoke参数:①代理类 ②代理类的静态属性(目标对象的方法Method,本例中是sayHello的Method) ③方法参数
public final void sayHello() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}