バイトコードプログラミング、Javassistパート3「Javassistを使用して実行時にクラスを再読み込みする」元のメソッドを置き換えて異なる結果を出力する


著者:小福兄の
ブログ:https://bugstack.cn

あなたと他の人が何かを手に入れることができるように、入金、共有、そして成長してください!

1.はじめに

上記2つのでjavassist基本的なコンテンツ、一般導入;細胞型(ClassPool)、クラス(CtClass)、属性(CtField)、方法(CtMethod)、使用時に、パラメトリックメソッドにパラメータの異なるタイプを作成することによって、基本的にこのコード構造をバイトコードプログラミングに使用する方法を習得できます。

さて、今日は使用しようとするjavassistクラスの内部に実装されている方法の内容を変更します。つまり、クラス情報は実行時に再ロードされます

それはあなたの通常であってもよいCRUDで、このような発展を期待していなかったバーン運転が、それは、使用中のシナリオをたくさん持っている、例えば、

  1. ホットデプロイメントは、主にそのようなシステムが頻繁に起動および停止できず、長時間かかるアプリケーションを起動できないため、本番環境で一般的に使用されます。
  2. 他のコンポーネント化されたリスク管理モデルパッケージは、外部で使用するためのものです。モデルパッケージがアップグレードされた場合、外部の再デプロイメントは不要であり、アップグレードを通知する必要もありません。
  3. さらに、それは開発とデバッグに使用され、コーディング効率を効果的に改善しコードファーマーの右手左手を解放できます

人間の脳は未知のものを作ることは難しいので、学ぶ必要があります。Brother FuのコードとCRUDを少なくしてください

関係するすべてのコードをプログラミングするバイトについて、に着目して缶公众号bugstackワームホールスタック、再:ソースコードは、取得されました。

第二に、開発環境

  1. JDK 1.8.0
  2. jdk1.8.0_161 \ libに\ tools.jarを-使用する必要jdiパッケージを
  3. javassist 3.12.1.GA

3.ケースの目的

ケースより多くのゴールを作るために色彩、我々は、シミュレート感謝航空機の妻は、システムを通して彼女のボーイフレンドは、照会危機のプロセスが緊急治療を必要とする、方法を。前女友数量

家族の調和を守り、危機を解決するために、クラスを動的にリロードし、謝の元ガールフレンドの数を変更し0て戻ってきました。次に、家族の調和を解決します。結局、飛行機に感謝することは報酬として私にお金を与えるでしょう

ドラフトユニオン、エースエンジニア、スタックからの申し込み

謝平面をパニックにする方法

public class ApiTest {

    public String queryGirlfriendCount(String boyfriendName) {
        return boyfriendName + "的前女友数量:" + (new Random().nextInt(10) + 1) + " 个";
    }

}

予測可能な結果 ;

你到底几个前女友!!!
谢飞机的前女友数量:3 个
谢飞机的前女友数量:5 个
谢飞机的前女友数量:8

4.技術の実現

1. HotSwapperオペレーションクラスのホットロード

ドラフトユニオン、エースエンジニア、申請

デラウェアアライアンスのエースエンジニア

/**
 * 公众号:bugstack虫洞栈
 * 博客栈:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
 * 本专栏是小傅哥多年从事一线互联网Java开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果能为您提供帮助,请给予支持(关注、点赞、分享)!
 */
public class GenerateClazzMethod {

    public static void main(String[] args) throws Exception {

        ApiTest apiTest = new ApiTest();
        System.out.println("你到底几个前女友!!!");

		      // 模拟谢飞机老婆一顿查询
        new Thread(() -> {
            while (true){
                System.out.println(apiTest.queryGirlfriendCount("谢飞机"));
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        
        // 监听 8000 端口,在启动参数里设置
        // java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
        HotSwapper hs = new HotSwapper(8000);

        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass = pool.get(ApiTest.class.getName());

        // 获取方法
        CtMethod ctMethod = ctClass.getDeclaredMethod("queryGirlfriendCount");
        // 重写方法
        ctMethod.setBody("{ return $1 + \"的前女友数量:\" + (0L) + \" 个\"; }");

        // 加载新的类
        System.out.println(":: 执行HotSwapper热插拔,修改谢飞机前女友数量为0个!");
        hs.reload(ApiTest.class.getName(), ctClass.toBytecode());

    }

}

2.知識ポイント

  1. マルチスレッドのシミュレーションループ呼び出し。このメソッドは常にクエリを実行します。クラスのその後の変更後、出力情報は異なります。
  2. javassist.tools.HotSwapperそれはjavassistロード操作に提供される熱パックの交換クラス。実行中は、JPDA(Java Platform Debugger Architecture)を有効にする必要があります。
  3. ctMethod.setBody書き換え方法の内容は、上記の2つの章で明確に説明されています。$ 1は取得メソッドの最初の入力パラメーターであり、中括弧{}は置換メソッドの本体です。
  4. 最後に、の使用hs.reload行う交換作業の熱負荷、ctClass.toBytecode()取得した後処理バイトコードクラス。

V.テスト結果

1. tools.jarを導入する

モジュール設定を開きます、引入tools.jar

2.pèizhì-agentlib

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

VMオプション、configure -agentlib

3.テストを実行する

Listening for transport dt_socket at address: 8000
你到底几个前女友!!!
谢飞机的前女友数量:3 个
谢飞机的前女友数量:5 个
谢飞机的前女友数量:8:: 执行HotSwapper热插拔,修改谢飞机前女友数量为0个!
谢飞机的前女友数量:4 个
谢飞机的前女友数量:5 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0 个
谢飞机的前女友数量:0...

Process finished with exit code -1

元ガールフレンドの数が0であることを確認したとき、Xie Aircraftは恥ずかしそうに笑い、エースエンジニアに4セントを与えるという彼の約束果たしました小傅哥

Xie Aircraftからの収益

4.効果のデモンストレーション

ホットローディング消火、4セント獲得に成功

6.まとめ

  1. まさか、どんなに優れたテクニックであっても、誰もそれを見ることはないでしょう。弟の飛行機にのみ穴をあけることができます!ドラフトユニオン、エースエンジニア、申請
  2. 実際のシーンでのクラスのホットロードと変更に関する操作は非常にたくさんありますが、一般的にはより厳しいシーンです。これは通常の開発では比較的まれであり、CRUD開発は発生しません。
  3. Javassist以下の場合ASM、この操作コードバイト一緒にパッケージを提供するためにAPIいくつかのシナリオではない考慮する必要があり、本当に良い操作JVMローカル変数とオペランドスタックを。ただし、より高いパフォーマンスが必要な場合は、その使用を検討できますASM
215元記事公開 ウォンの賞賛387 ビューに25万+を

おすすめ

転載: blog.csdn.net/Yao__Shun__Yu/article/details/105671756