過去2日間で、冬眠の代理部分を見ました。最初の反応は、基礎となる層が反射を使用し、ユーザーエンティティのプロキシクラスを生成したことでした。後で、リフレクションには新しいクラスを生成する能力がないことに気付いたので、自然にJavassist(ダウンロードアドレス)を見つけました。
オンラインで検索されたチュートリアルのほとんどは、Javassist APIに説明されていますが、最終的にはロードプロセスがないことがよくあります。著者がクラスの読み込みのためにこれらのチュートリアルを模倣する場合、ロードされた結果は元のクラスであり、ByteCodeが変更されたコンテンツはありません。
いくつかの調査の後、著者は、インターネット上のほとんどのチュートリアルの最後のステップであるBytecodeの保存を使用してBytecodeを保存することを発見しました。関数構造をチェックした後、文字列タイプの過負荷もあることがわかりました。 Eclipseの下では、バイトコードのルート位置は「.//」ではなく、「.//bin」であり、WriteFileの別の過負荷がバイトコードのルート位置を指定するパラメーターである可能性があります。いくつかの変更の後、私はそれが真実であることがわかりました。
以下はデモコードです。
これが著者のプロジェクトの構造です。
editable.java:パッケージcom.thrblock.javassist; public class editable {public void showinfo(){system.out.println( "infodefault!"); }} main.java:パッケージcom.thrblock.javassist; Import java.io.ioexception; Import javassist.cannotcompileexception; Import javassist.classpool; Import javassist.ctclass; Import javassist.ctmethod; Import javassist.ctnewmethod; import javassist.notfoundist.notfundecist.notfundext.; args){classpool pool = classpool.getDefault(); try {pool.insertclasspath( ".// bin"); //ルートパスを設定します。 (ここに設定されたルートパスは、明らかにwritefileで使用されていません) ctnewmethod.make( "public void showinfo(){super.showinfo(); system.out.println(/" custominserthaha!/");}"、cc); //メソッドを追加します。 cc.addmethod(cm); cc.writefile( ".// bin"); //これはより重要です。 NULLパラメーターの結果は、Eclipseバイトコードルートパスに保存されないことです。 } catch(notfoundexception | can count councompileexception | ioexception e){e.printstacktrace();} try {class <?冬眠。 ed.showinfo(); //メソッドの呼び出し。 } catch(classNotFoundException | InstantiationException | Illegalaccessexception e){e.printstacktrace();}}}}印刷結果:
InfodeFault!
Custominserthaha!
その他のメモ:
クラスを生成したため、クラス名が元のクラス名と同じ場合、クラスファイルが上書きされます。ただし、変更前にクラスがJVMによってロードされている場合、変更された部品は有効になり、JVMを再起動する必要があります。
要約します
上記は、Eclipseの下でのJavassistの正しい使用方法に関するこの記事のすべての内容です。私はそれが誰にでも役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!