publicinterfaceIHello{voidsay();}publicclassHelloImplimplementsIHello{@Overridepublicvoidsay(){System.out.println("hello!");}}publicclassDynamicProxyimplementsInvocationHandler{privateObjectobject;publicObjectbind(Objectobject){this.object=object;returnProxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);}@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("ready to say : ");returnmethod.invoke(this.object,args);}}publicclassMain{publicstaticvoidmain(String[]args){IHellohello=newHelloImpl();IHelloiHello=(IHello)newDynamicProxy().bind(hello);iHello.say();}}
privatestaticClass<?>defineProxyClass(Modulem,List<Class<?>>interfaces){StringproxyPkg=null;// package to define proxy class in
intaccessFlags=Modifier.PUBLIC|Modifier.FINAL;/*
* Record the package of a non-public proxy interface so that the
* proxy class will be defined in the same package. Verify that
* all non-public proxy interfaces are in the same package.
*/for(Class<?>intf:interfaces){intflags=intf.getModifiers();if(!Modifier.isPublic(flags)){accessFlags=Modifier.FINAL;// non-public, final
Stringpkg=intf.getPackageName();if(proxyPkg==null){proxyPkg=pkg;}elseif(!pkg.equals(proxyPkg)){thrownewIllegalArgumentException("non-public interfaces from different packages");}}}if(proxyPkg==null){// all proxy interfaces are public
proxyPkg=m.isNamed()?PROXY_PACKAGE_PREFIX+"."+m.getName():PROXY_PACKAGE_PREFIX;}elseif(proxyPkg.isEmpty()&&m.isNamed()){thrownewIllegalArgumentException("Unnamed package cannot be added to "+m);}if(m.isNamed()){if(!m.getDescriptor().packages().contains(proxyPkg)){thrownewInternalError(proxyPkg+" not exist in "+m.getName());}}/*
* Choose a name for the proxy class to generate.
* 生成的动态代理类名字
*/longnum=nextUniqueNumber.getAndIncrement();StringproxyName=proxyPkg.isEmpty()?proxyClassNamePrefix+num:proxyPkg+"."+proxyClassNamePrefix+num;ClassLoaderloader=getLoader(m);trace(proxyName,m,loader,interfaces);/*
* Generate the specified proxy class.
* 生成动态代理类
*/byte[]proxyClassFile=ProxyGenerator.generateProxyClass(proxyName,interfaces.toArray(EMPTY_CLASS_ARRAY),accessFlags);try{Class<?>pc=UNSAFE.defineClass(proxyName,proxyClassFile,0,proxyClassFile.length,loader,null);reverseProxyCache.sub(pc).putIfAbsent(loader,Boolean.TRUE);returnpc;}catch(ClassFormatErrore){/*
* 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).
*/thrownewIllegalArgumentException(e.toString());}}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
packagecom.sun.proxy;importcom.example.demo.web.IHello;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;importjava.lang.reflect.UndeclaredThrowableException;publicfinalclass$Proxy0extendsProxyimplementsIHello{privatestaticMethodm1;privatestaticMethodm2;privatestaticMethodm3;privatestaticMethodm0;public$Proxy0(InvocationHandlervar1)throws{super(var1);}publicfinalbooleanequals(Objectvar1)throws{try{return(Boolean)super.h.invoke(this,m1,newObject[]{var1});}catch(RuntimeException|Errorvar3){throwvar3;}catch(Throwablevar4){thrownewUndeclaredThrowableException(var4);}}publicfinalStringtoString()throws{try{return(String)super.h.invoke(this,m2,(Object[])null);}catch(RuntimeException|Errorvar2){throwvar2;}catch(Throwablevar3){thrownewUndeclaredThrowableException(var3);}}publicfinalvoidsay()throws{try{super.h.invoke(this,m3,(Object[])null);}catch(RuntimeException|Errorvar2){throwvar2;}catch(Throwablevar3){thrownewUndeclaredThrowableException(var3);}}publicfinalinthashCode()throws{try{return(Integer)super.h.invoke(this,m0,(Object[])null);}catch(RuntimeException|Errorvar2){throwvar2;}catch(Throwablevar3){thrownewUndeclaredThrowableException(var3);}}static{try{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.example.demo.web.IHello").getMethod("say");m0=Class.forName("java.lang.Object").getMethod("hashCode");}catch(NoSuchMethodExceptionvar2){thrownewNoSuchMethodError(var2.getMessage());}catch(ClassNotFoundExceptionvar3){thrownewNoClassDefFoundError(var3.getMessage());}}}