Java動的エージェント生成コードの表示

28758 ワード

Java動的エージェント生成コードの表示
1.生成クラスをエクスポートするagentを作成する
agentはjvmと付き合うためのもので、静的public static void premain(String agentArgs,Instrumentation inst)メソッドを実現する必要があります.私は次のコードを使用してagentを作成します.
package ctgu.jagent;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;

public class CustomAgent implements ClassFileTransformer {
 
    public static void premain(String agentArgs, Instrumentation inst) {
        inst.addTransformer(new CustomAgent());
    }

    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        if (!className.startsWith("java") && !className.startsWith("sun")) {
            //    java   sun   
            //     
            int lastIndexOf = className.lastIndexOf("/") + 1;
            String fileName = className.substring(lastIndexOf) + ".class";
            exportClazzToFile("E:/javaeeworkspace/bytecode/exported/", fileName, classfileBuffer);
            System.out.println(className + " --> EXPORTED Succeess!");
        }    
        return classfileBuffer;
    }

    /**
     * 
     * @param dirPath
     *   /  ,     
     * @param fileName
     * @param data
     */
    private void exportClazzToFile(String dirPath, String fileName, byte[] data) {
        try {
            File file = new File(dirPath + fileName);
            if (!file.exists()) {
                file.createNewFile();    
            }    
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data);
            fos.close();    
        } catch (Exception e) {
            System.out.println("exception occured while doing some file operation");
            e.printStackTrace();
        }
    }
}

次にeclipseのエクスポート機能を使用してjarをエクスポートし(agentはjarの形式で存在しなければならないことに注意)、ウィザードで指定したMANIFEST.MFファイルを使用し、MANIFEST.MFファイルの内容は以下の通りです.
Manifest-Version: 1.0
Premain-Class: ctgu.jagent.CustomAgent

このpremain-Classはpremain静的メソッドを持つクラスであることに注意してください.mavenを使用する場合は、次のpluginも使用できます.
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
        </archive>
    </configuration>
</plugin>

manifestFileをカスタムMANIFEST.MFを格納するパスに変えて、mvn packageでいいです.
エクスポートされたjarパッケージはjagent.jarと仮定します.
2.jagent.jarの使用
jagent.jarを工事の下に置いて、運行する時jvmパラメータを加えます
-javaagent:jagent.jar

注意:左右にスペースはありませんが、jvmプロンプトが見つからない場合は、eclispeでjagent.jarをbuildpathに追加できます.
3.動的エージェントの使用
3.0元のターゲットのインタフェースと実装
インタフェースの定義は次のとおりです.
package ctgu.bytecode.proxy.service;

public interface HelloService {
 public String sayHello(String name) ;
}

次のようになります.
package ctgu.bytecode.proxy.service.impl;    
import ctgu.bytecode.proxy.service.HelloService;    
public class HelloServiceImpl implements HelloService{    
    @Override
    public String sayHello(String name) {
        return "Hello "+name;
    }       
}

3.1 jdkを使用するエージェント
private static void javaDynamicProxy() {
    HelloService helloService=new HelloServiceImpl();
    MyInvocationHandler handler=new MyInvocationHandler(helloService);
    
    HelloService proxy = (HelloService)Proxy.newProxyInstance(HelloService.class.getClassLoader(), 
            new Class<?>[]{HelloService.class}, handler);
    
    
    String sayHello = proxy.sayHello("woober");
    
    System.out.println(sayHello);
}

MyInvocationHandlerのコードは次のとおりです.
package ctgu.bytecode.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {

    Object trueTarget;
    
    public MyInvocationHandler(Object target) {
        this.trueTarget=target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before invoke method:"+method.getName());
        Object result = method.invoke(trueTarget, args);
        System.out.println("invoke finish return:"+result);
        return result;
    }

}

実行後の出力:
ctgu/bytecode/TestMain --> EXPORTED Succeess!    
ctgu/bytecode/proxy/service/impl/HelloServiceImpl --> EXPORTED Succeess!
ctgu/bytecode/proxy/service/HelloService --> EXPORTED Succeess!
ctgu/bytecode/proxy/MyInvocationHandler --> EXPORTED Succeess!
com/sun/proxy/$Proxy0 --> EXPORTED Succeess!
before invoke method:sayHello
invoke finish return:Hello woober
Hello woober

第4部ではcom/sun/proxy/$Proxy 0を生成する逆コンパイルコードを解析します.
3.2 cglibエージェントの使用
private static void cgLibProxy(){       
    HelloService helloService=new HelloServiceImpl();
    MyMethodIntercepter intercepter=new MyMethodIntercepter(helloService);       
    HelloService proxy = (HelloService)Enhancer.create(HelloService.class,intercepter);
    System.err.println("Proxy class name is "+proxy.getClass().getName());
    System.out.println(proxy.sayHello("Woober"));
}

MyMethodIntercepterコードは次のとおりです.
package ctgu.bytecode.proxy;

import java.lang.reflect.Method;    
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MyMethodIntercepter  implements MethodInterceptor{

    Object trueTarget;
    
    public MyMethodIntercepter(Object target) {
         trueTarget=target;
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("In cglib before invoke");
        //  methodProxy           ,                  
         Object result = proxy.invoke(trueTarget, args);
        System.out.println("In cglib after invoke");
        return result;
    }
}

出力の実行:
ctgu/bytecode/TestMain --> EXPORTED Succeess!
net/sf/cglib/proxy/Callback --> EXPORTED Succeess!
ctgu/bytecode/proxy/service/impl/HelloServiceImpl --> EXPORTED Succeess!
ctgu/bytecode/proxy/service/HelloService --> EXPORTED Succeess!
ctgu/bytecode/proxy/MyMethodIntercepter --> EXPORTED Succeess!
net/sf/cglib/proxy/MethodInterceptor --> EXPORTED Succeess!
net/sf/cglib/proxy/Enhancer --> EXPORTED Succeess!
      cglib    asm  .....  

ctgu/bytecode/proxy/service/HelloService$$EnhancerByCGLIB$$1af19a1d --> EXPORTED Succeess!

net/sf/cglib/proxy/MethodProxy --> EXPORTED Succeess!
net/sf/cglib/proxy/MethodProxy$CreateInfo --> EXPORTED Succeess!

In cglib before invoke

Proxy class name is ctgu.bytecode.proxy.service.HelloService$$EnhancerByCGLIB$$1af19a1d

    cglib  ...

ctgu/bytecode/proxy/service/HelloService$$FastClassByCGLIB$$c2826506 --> EXPORTED Succeess!

ctgu/bytecode/proxy/service/HelloService$$EnhancerByCGLIB$$1af19a1d$$FastClassByCGLIB$$a45a31f6 --> EXPORTED Succeess!

In cglib after invoke

Hello Woober

この二つの言葉の順序に注意する
In cglib before invoke
Proxy class name is ctgu.bytecode.proxy.service.HelloService$$EnhancerByCGLIB$$1af19a1d

私はシステム.errで打ったProxy class name isという文を使っているので、outと同じストリームではないので、順番が間違っています(errはeclipseで赤く表示されるので、きれいです...)
次にctgu.bytecode.proxy.service.HelloServices[EnhancerByCGLIB]1 af 19 a 1 dというクラスに注目する
4.生成クラスのソースコードの表示
ついでの反コンパイラを探して、私はBytecode Viewerを使って、githubアドレスhttps://github.com/Konloch/bytecode-viewer
4.1 JDK動的エージェント逆コンパイル
/*
 * Decompiled with CFR 0_110.
 * 
 * Could not load the following classes:
 *  com.sun.proxy.$Proxy0
 *  ctgu.bytecode.proxy.service.HelloService
 */
package com.sun.proxy;

import ctgu.bytecode.proxy.service.HelloService;
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 HelloService {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public $Proxy0(InvocationHandler invocationHandler) {
        super(invocationHandler);
    }

    public final boolean equals(Object object) {
        try {
            return (Boolean)this.h.invoke((Object)this, m1, new Object[]{object});
        }
        catch (Error | RuntimeException v0) {
            throw v0;
        }
        catch (Throwable var2_2) {
            throw new UndeclaredThrowableException(var2_2);
        }
    }

    public final String sayHello(String string) {
        try {
            return (String)this.h.invoke((Object)this, m3, new Object[]{string});
        }
        catch (Error | RuntimeException v0) {
            throw v0;
        }
        catch (Throwable var2_2) {
            throw new UndeclaredThrowableException(var2_2);
        }
    }

    public final String toString() {
        try {
            return (String)this.h.invoke((Object)this, m2, null);
        }
        catch (Error | RuntimeException v0) {
            throw v0;
        }
        catch (Throwable var1_1) {
            throw new UndeclaredThrowableException(var1_1);
        }
    }

    public final int hashCode() {
        try {
            return (Integer)this.h.invoke((Object)this, m0, null);
        }
        catch (Error | RuntimeException v0) {
            throw v0;
        }
        catch (Throwable var1_1) {
            throw new UndeclaredThrowableException(var1_1);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("ctgu.bytecode.proxy.service.HelloService").getMethod("sayHello", Class.forName("java.lang.String"));
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
            return;
        }
        catch (NoSuchMethodException var1) {
            throw new NoSuchMethodError(var1.getMessage());
        }
        catch (ClassNotFoundException var1_1) {
            throw new NoClassDefFoundError(var1_1.getMessage());
        }
    }
}

HelloServiceインタフェースを実装しsayHelloメソッドを実装していることがわかり,実際に呼び出されたときに使用されていたinvocationHandlerがm 3に伝わり,m 3は実際に反射によって得られたインタフェースのsayHelloメソッドである.
m3 = Class.forName("ctgu.bytecode.proxy.service.HelloService").getMethod("sayHello", Class.forName("java.lang.String"));

4.2 CGLIBダイナミックエージェント逆コンパイル
package ctgu.bytecode.proxy.service;

import java.lang.reflect.*;
import net.sf.cglib.proxy.*;
import net.sf.cglib.core.*;

public class HelloService$$EnhancerByCGLIB$$1af19a1d implements HelloService, Factory
{
    private boolean CGLIB$BOUND;
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    private MethodInterceptor CGLIB$CALLBACK_0;
    private static final Method CGLIB$finalize$0$Method;
    private static final MethodProxy CGLIB$finalize$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;
    private static final Method CGLIB$sayHello$5$Method;
    private static final MethodProxy CGLIB$sayHello$5$Proxy;
    
    static void CGLIB$STATICHOOK1() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];
        final Class<?> forName = Class.forName("ctgu.bytecode.proxy.service.HelloService$$EnhancerByCGLIB$$1af19a1d");
        final Class<?> forName2;
        final Method[] methods = ReflectUtils.findMethods(new String[] { "finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (forName2 = Class.forName("java.lang.Object")).getDeclaredMethods());
        CGLIB$finalize$0$Method = methods[0];
        CGLIB$finalize$0$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()V", "finalize", "CGLIB$finalize$0");
        CGLIB$equals$1$Method = methods[1];
        CGLIB$equals$1$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
        CGLIB$toString$2$Method = methods[2];
        CGLIB$toString$2$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
        CGLIB$hashCode$3$Method = methods[3];
        CGLIB$hashCode$3$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()I", "hashCode", "CGLIB$hashCode$3");
        CGLIB$clone$4$Method = methods[4];
        CGLIB$clone$4$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
        final Class<?> forName3;
        CGLIB$sayHello$5$Method = ReflectUtils.findMethods(new String[] { "sayHello", "(Ljava/lang/String;)Ljava/lang/String;" }, (forName3 = Class.forName("ctgu.bytecode.proxy.service.HelloService")).getDeclaredMethods())[0];
        CGLIB$sayHello$5$Proxy = MethodProxy.create((Class)forName3, (Class)forName, "(Ljava/lang/String;)Ljava/lang/String;", "sayHello", "CGLIB$sayHello$5");
    }
    
    final void CGLIB$finalize$0() throws Throwable {
        super.finalize();
    }
    
    protected final void finalize() throws Throwable {
        MethodInterceptor cglib$CALLBACK_2;
        MethodInterceptor cglib$CALLBACK_0;
        if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
            CGLIB$BIND_CALLBACKS(this);
            cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
        }
        if (cglib$CALLBACK_0 != null) {
            cglib$CALLBACK_2.intercept((Object)this, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$finalize$0$Method, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$emptyArgs, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$finalize$0$Proxy);
            return;
        }
        super.finalize();
    }
    
    final boolean CGLIB$equals$1(final Object o) {
        return super.equals(o);
    }
    
    public final boolean equals(final Object o) {
        MethodInterceptor cglib$CALLBACK_2;
        MethodInterceptor cglib$CALLBACK_0;
        if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
            CGLIB$BIND_CALLBACKS(this);
            cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
        }
        if (cglib$CALLBACK_0 != null) {
            final Object intercept = cglib$CALLBACK_2.intercept((Object)this, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$equals$1$Method, new Object[] { o }, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$equals$1$Proxy);
            return intercept != null && (boolean)intercept;
        }
        return super.equals(o);
    }
    
    final String CGLIB$toString$2() {
        return super.toString();
    }
    
    public final String toString() {
        MethodInterceptor cglib$CALLBACK_2;
        MethodInterceptor cglib$CALLBACK_0;
        if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
            CGLIB$BIND_CALLBACKS(this);
            cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
        }
        if (cglib$CALLBACK_0 != null) {
            return (String)cglib$CALLBACK_2.intercept((Object)this, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$toString$2$Method, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$emptyArgs, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$toString$2$Proxy);
        }
        return super.toString();
    }
    
    final int CGLIB$hashCode$3() {
        return super.hashCode();
    }
    
    public final int hashCode() {
        MethodInterceptor cglib$CALLBACK_2;
        MethodInterceptor cglib$CALLBACK_0;
        if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
            CGLIB$BIND_CALLBACKS(this);
            cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
        }
        if (cglib$CALLBACK_0 != null) {
            final Object intercept = cglib$CALLBACK_2.intercept((Object)this, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$hashCode$3$Method, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$emptyArgs, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$hashCode$3$Proxy);
            return (intercept == null) ? 0 : ((Number)intercept).intValue();
        }
        return super.hashCode();
    }
    
    final Object CGLIB$clone$4() throws CloneNotSupportedException {
        return super.clone();
    }
    
    protected final Object clone() throws CloneNotSupportedException {
        MethodInterceptor cglib$CALLBACK_2;
        MethodInterceptor cglib$CALLBACK_0;
        if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
            CGLIB$BIND_CALLBACKS(this);
            cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
        }
        if (cglib$CALLBACK_0 != null) {
            return cglib$CALLBACK_2.intercept((Object)this, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$clone$4$Method, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$emptyArgs, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$clone$4$Proxy);
        }
        return super.clone();
    }
    
    final String CGLIB$sayHello$5(final String s) {
        return super.sayHello(s);
    }
    
    public final String sayHello(final String s) {
        MethodInterceptor cglib$CALLBACK_2;
        MethodInterceptor cglib$CALLBACK_0;
        if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
            CGLIB$BIND_CALLBACKS(this);
            cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
        }
        if (cglib$CALLBACK_0 != null) {
            return (String)cglib$CALLBACK_2.intercept((Object)this, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$sayHello$5$Method, new Object[] { s }, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$sayHello$5$Proxy);
        }
        return super.sayHello(s);
    }
    
    public static MethodProxy CGLIB$findMethodProxy(final Signature signature) {
        final String string = signature.toString();
        switch (string.hashCode()) {
            case -1816210712: {
                if (string.equals("sayHello(Ljava/lang/String;)Ljava/lang/String;")) {
                    return HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$sayHello$5$Proxy;
                }
                break;
            }
            case -1574182249: {
                if (string.equals("finalize()V")) {
                    return HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$finalize$0$Proxy;
                }
                break;
            }
            case -508378822: {
                if (string.equals("clone()Ljava/lang/Object;")) {
                    return HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$clone$4$Proxy;
                }
                break;
            }
            case 1826985398: {
                if (string.equals("equals(Ljava/lang/Object;)Z")) {
                    return HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$equals$1$Proxy;
                }
                break;
            }
            case 1913648695: {
                if (string.equals("toString()Ljava/lang/String;")) {
                    return HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$toString$2$Proxy;
                }
                break;
            }
            case 1984935277: {
                if (string.equals("hashCode()I")) {
                    return HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$hashCode$3$Proxy;
                }
                break;
            }
        }
        return null;
    }
    
    public HelloService$$EnhancerByCGLIB$$1af19a1d() {
        CGLIB$BIND_CALLBACKS(this);
    }
    
    public static void CGLIB$SET_THREAD_CALLBACKS(final Callback[] array) {
        HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$THREAD_CALLBACKS.set(array);
    }
    
    public static void CGLIB$SET_STATIC_CALLBACKS(final Callback[] cglib$STATIC_CALLBACKS) {
        CGLIB$STATIC_CALLBACKS = cglib$STATIC_CALLBACKS;
    }
    
    private static final void CGLIB$BIND_CALLBACKS(final Object o) {
        final HelloService$$EnhancerByCGLIB$$1af19a1d helloService$$EnhancerByCGLIB$$1af19a1d = (HelloService$$EnhancerByCGLIB$$1af19a1d)o;
        if (!helloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$BOUND) {
            helloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$BOUND = true;
            Object o2;
            if ((o2 = HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$THREAD_CALLBACKS.get()) != null || (o2 = HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$STATIC_CALLBACKS) != null) {
                helloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])o2)[0];
            }
        }
    }
    
    public Object newInstance(final Callback[] array) {
        CGLIB$SET_THREAD_CALLBACKS(array);
        final HelloService$$EnhancerByCGLIB$$1af19a1d helloService$$EnhancerByCGLIB$$1af19a1d = new HelloService$$EnhancerByCGLIB$$1af19a1d();
        CGLIB$SET_THREAD_CALLBACKS(null);
        return helloService$$EnhancerByCGLIB$$1af19a1d;
    }
    
    public Object newInstance(final Callback callback) {
        CGLIB$SET_THREAD_CALLBACKS(new Callback[] { callback });
        final HelloService$$EnhancerByCGLIB$$1af19a1d helloService$$EnhancerByCGLIB$$1af19a1d = new HelloService$$EnhancerByCGLIB$$1af19a1d();
        CGLIB$SET_THREAD_CALLBACKS(null);
        return helloService$$EnhancerByCGLIB$$1af19a1d;
    }
    
    public Object newInstance(final Class[] array, final Object[] array2, final Callback[] array3) {
        CGLIB$SET_THREAD_CALLBACKS(array3);
        switch (array.length) {
            case 0: {
                final HelloService$$EnhancerByCGLIB$$1af19a1d helloService$$EnhancerByCGLIB$$1af19a1d = new HelloService$$EnhancerByCGLIB$$1af19a1d();
                CGLIB$SET_THREAD_CALLBACKS(null);
                return helloService$$EnhancerByCGLIB$$1af19a1d;
            }
            default: {
                throw new IllegalArgumentException("Constructor not found");
            }
        }
    }
    
    public Callback getCallback(final int n) {
        CGLIB$BIND_CALLBACKS(this);
        Object cglib$CALLBACK_0 = null;
        switch (n) {
            case 0: {
                cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0;
                break;
            }
            default: {
                cglib$CALLBACK_0 = null;
                break;
            }
        }
        return (Callback)cglib$CALLBACK_0;
    }
    
    public void setCallback(final int n, final Callback callback) {
        switch (n) {
            case 0: {
                this.CGLIB$CALLBACK_0 = (MethodInterceptor)callback;
                break;
            }
        }
    }
    
    public Callback[] getCallbacks() {
        CGLIB$BIND_CALLBACKS(this);
        return new Callback[] { this.CGLIB$CALLBACK_0 };
    }
    
    public void setCallbacks(final Callback[] array) {
        this.CGLIB$CALLBACK_0 = (MethodInterceptor)array[0];
    }
    
    static {
        CGLIB$STATICHOOK1();
    }
}

生成されたクラスは、HelloServiceインタフェースを実装し、Factoryインタフェースを実装します.Factoryインタフェースは次のとおりです.
public interface Factory {
    
    Object newInstance(Callback callback);      
     
    Object newInstance(Callback[] callbacks);   
    
    Object newInstance(Class[] types, Object[] args, Callback[] callbacks); 
   
    Callback getCallback(int index);
 
    void setCallback(int index, Callback callback); 
    
    void setCallbacks(Callback[] callbacks);    
     
    Callback[] getCallbacks();
}

生成されたsayHello実装を直接見る
  public final String sayHello(final String s) {
        MethodInterceptor cglib$CALLBACK_2;
        MethodInterceptor cglib$CALLBACK_0;
        if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
            CGLIB$BIND_CALLBACKS(this);
            cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
        }
        if (cglib$CALLBACK_0 != null) {
            return (String)cglib$CALLBACK_2.intercept((Object)this, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$sayHello$5$Method, new Object[] { s }, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$sayHello$5$Proxy);
        }
        return super.sayHello(s);
    }

cglib(CALLBACK_0はCGLIB)BIND_CALLBACKS(this)が完成した、glib(CALLBACK_2とglib)CALLBACK_2は一つのものです.
CGLIB$BINDを見てみましょうCALLBACKS(this)は何をしましたか?
private static final void CGLIB$BIND_CALLBACKS(final Object o) {
    final HelloService$$EnhancerByCGLIB$$1af19a1d helloService$$EnhancerByCGLIB$$1af19a1d = (HelloService$$EnhancerByCGLIB$$1af19a1d)o;
    if (!helloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$BOUND) {
        helloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$BOUND = true;
        Object o2;
        if ((o2 = HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$THREAD_CALLBACKS.get()) != null || (o2 = HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$STATIC_CALLBACKS) != null) {
            helloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])o2)[0];
        }
    }
}

CGLIB(CALLBACK_0はCGLIB)THREAD_CALLBACKS.get()またはCGLIB(STATIC_CALLBACKS,CGLIB)THREAD_CALLBACKSはthreadlocalのメンバー変数です.
CGLIB(THREAD_CALLBACKSは以下のCGLIB)SET_THREAD_CALLBACKSメソッドで設定した、
public static void CGLIB$SET_THREAD_CALLBACKS(final Callback[] array) {
    HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$THREAD_CALLBACKS.set(array);
}

この方法はFactoryインタフェースのnewInstanceによって呼び出される
public Object newInstance(final Callback[] array) {
    CGLIB$SET_THREAD_CALLBACKS(array);
    final HelloService$$EnhancerByCGLIB$$1af19a1d helloService$$EnhancerByCGLIB$$1af19a1d = new HelloService$$EnhancerByCGLIB$$1af19a1d();
    CGLIB$SET_THREAD_CALLBACKS(null);
    return helloService$$EnhancerByCGLIB$$1af19a1d;
}

public Object newInstance(final Callback callback) {
    CGLIB$SET_THREAD_CALLBACKS(new Callback[] { callback });
    final HelloService$$EnhancerByCGLIB$$1af19a1d helloService$$EnhancerByCGLIB$$1af19a1d = new HelloService$$EnhancerByCGLIB$$1af19a1d();
    CGLIB$SET_THREAD_CALLBACKS(null);
    return helloService$$EnhancerByCGLIB$$1af19a1d;
}

彼がなぜCGLIB(SET_THREAD_CALLBACKS(array);その後CGLIB)SET_THREAD_CALLBACKS(null); ???逆コンパイルの問題?
CGLIB$STATIC_の場合CALLBACKSは
public static void CGLIB$SET_STATIC_CALLBACKS(final Callback[] cglib$STATIC_CALLBACKS) {
    CGLIB$STATIC_CALLBACKS = cglib$STATIC_CALLBACKS;
}

この方法は値を付けたが、呼び出す場所が見つからなかった.
最後に実際に実行する方法を見ると、落としたintercepterのintercept方法です.
(String)cglib$CALLBACK_2.intercept((Object)this, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$sayHello$5$Method, new Object[] { s }, HelloService$$EnhancerByCGLIB$$1af19a1d.CGLIB$sayHello$5$Proxy);

最後のパラメータはMethodProxyです
 CGLIB$sayHello$5$Proxy = MethodProxy.create((Class)forName3, (Class)forName, "(Ljava/lang/String;)Ljava/lang/String;", "sayHello", "CGLIB$sayHello$5");

メソッドに対してエージェントが生成されたと思います
final String CGLIB$sayHello$5(final String s) {
    return super.sayHello(s);
}

このcglibが生成したバイトコードについては,多くの逆コンパイルツールでは解析できない.上記の生成コードの正確性は保証されません