Javassist 實現(xiàn)AOP、動態(tài)創(chuàng)建代碼

Javassist是基于ASM,提供了更高級的API,執(zhí)行效率比ASM差一些,但無需掌握字節(jié)碼指令的知識,對使用者要求較低,多數(shù)的Android熱修復(fù)框架都是基于Javassist實現(xiàn)。

代表框架:InstantRun、HotFix。

動態(tài)代理教程

添加依賴

implementation 'org.javassist:javassist:3.25.0-GA'

代碼

public class JavassistTest implements MethodHandler {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        User user = new JavassistTest().getProxy(User.class);
        user.setId(1);
        System.out.println("Id: "+user.getId());
    }
    private <T> T getProxy(Class<T> clazz) throws InstantiationException, IllegalAccessException {
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setSuperclass(clazz);
        Class<?> proxyClass = proxyFactory.createClass();
        T result = (T)proxyClass.newInstance();
        ((ProxyObject)result).setHandler(this);
        return result;
    }
    @Override
    public Object invoke(Object obj, Method thisMethod, Method method, Object[] args) throws Throwable {
        System.out.println("執(zhí)行開始:" + method);
        Object result = method.invoke(obj, args);
        System.out.println("執(zhí)行結(jié)束:" + method);
        return result;
    }
    public static class User {
        private int id;
        public int getId() {return id;}
        public void setId(int id) {this.id = id;}
    }
}

結(jié)果

執(zhí)行開始:public final void com.thejoyrun.aptpreferences.JavassistTest$User_$$_jvst617_0._d8setId(int)
執(zhí)行結(jié)束:public final void com.thejoyrun.aptpreferences.JavassistTest$User_$$_jvst617_0._d8setId(int)
執(zhí)行開始:public final int com.thejoyrun.aptpreferences.JavassistTest$User_$$_jvst617_0._d4getId()
執(zhí)行結(jié)束:public final int com.thejoyrun.aptpreferences.JavassistTest$User_$$_jvst617_0._d4getId()
Id: 1

動態(tài)創(chuàng)建代碼

public class JavassistDefineClassTest {
    public static void main(String[] args) throws CannotCompileException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        // 創(chuàng)建類池,true 表示使用默認(rèn)路徑
        ClassPool classPool = new ClassPool(true);
        CtClass ctClass = classPool.makeClass("User");
        ctClass.addField(CtField.make("private int id;", ctClass));
        ctClass.addMethod(CtNewMethod.make("public void setId(int id) {this.id = id;}", ctClass));
        ctClass.addMethod(CtNewMethod.make("public int getId() {return id;}", ctClass));
        Class testClass = ctClass.toClass();
        Object object = testClass.newInstance();
        Method setMethod = testClass.getMethod("setId", int.class);
        Method getMethod = testClass.getMethod("getId");

        setMethod.invoke(object, 101);
        System.out.println("userId: "+getMethod.invoke(object));
    }
}

結(jié)果

userId: 101
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容