Jika kelas proxy sudah ada sebelum program berjalan, maka metode proxy ini disebut proxy statis. Dalam hal ini, kelas proxy biasanya didefinisikan dalam kode Java. Biasanya, kelas proxy dan kelas delegasi di proxy statis mengimplementasikan antarmuka yang sama atau berasal dari kelas induk yang sama.
1. Ikhtisar
1. Apa itu agen
Kita semua tahu bahwa agen WeChat hanya menjual barang atas nama produsen, dan produsen "mempercayakan" agen untuk menjual barang untuk mereka. Mengenai agen bisnis WeChat, pertama -tama, ketika kami membeli barang -barang dari mereka, kami biasanya tidak tahu siapa pabrikannya, yaitu, "komisaris" tidak terlihat oleh kami; Kedua, agen bisnis WeChat terutama menargetkan orang di lingkaran teman sebagai pelanggan mereka, yang setara dengan "filter" grup pelanggan untuk produsen. Kami lebih jauh abstrak agen dan produsen mikro-bisnis. Yang pertama dapat diabstraksikan sebagai kelas agen, dan yang terakhir dapat diabstraksi sebagai kelas delegasi (kelas agen). Dengan menggunakan proxy, biasanya ada dua keuntungan dan dapat sesuai dengan dua karakteristik agen mikro-bisnis yang kami sebutkan:
Keuntungan 1: dapat menyembunyikan implementasi kelas delegasi;
Keuntungan 2: Ini dapat mencapai decoupling antara klien dan kelas delegasi, dan dapat melakukan beberapa pemrosesan tambahan tanpa memodifikasi kode kelas delegasi.
2. Proxy statis
Jika kelas proxy sudah ada sebelum program berjalan, maka metode proxy ini disebut proxy statis. Dalam hal ini, kelas proxy biasanya didefinisikan dalam kode Java. Biasanya, kelas proxy dan kelas delegasi di proxy statis mengimplementasikan antarmuka yang sama atau berasal dari kelas induk yang sama. Di bawah ini kami menggunakan kelas vendor untuk mewakili produsen dan kelas BusinessAgent untuk mewakili agen mikro-bisnis untuk memperkenalkan implementasi sederhana dari agen statis. Baik kelas delegasi dan kelas proxy mengimplementasikan antarmuka jual. Definisi antarmuka jual adalah sebagai berikut:
Jual Antarmuka Publik {Void Sell (); void ad (); } Definisi kelas vendor adalah sebagai berikut: Vendor kelas publik mengimplementasikan menjual {public void sell () {System.out.println ("dalam metode jual"); } public void ad () {System, out.println ("Metode iklan")}} Definisi Kelas Proxy BusinessAgent adalah sebagai berikut:
Vendor kelas publik mengimplementasikan penjualan {public void sell () {System.out.println ("dalam metode jual"); } public void ad () {System, out.println ("Metode iklan")}} Dari definisi kelas BusinessAgent, kami dapat memahami bahwa agen statis dapat diimplementasikan melalui agregasi, sehingga kelas agen dapat memiliki referensi ke kelas delegasi.
Mari kita pertimbangkan persyaratan ini di bawah ini: Tambahkan fungsi penyaringan ke kelas vendor dan jual barang hanya kepada mahasiswa. Melalui proxy statis, kita dapat mencapainya tanpa memodifikasi kode kelas vendor. Kami hanya perlu menambahkan penilaian ke metode jual di kelas bisnis dan bisa seperti berikut:
Implements BusinessAgent kelas publik menjual {... public void jual () {if (isColleDesudent ()) {vendor.sell (); }} ...} Ini sesuai dengan keuntungan kedua dari menggunakan proxy yang disebutkan di atas: dapat mencapai decoupling antara klien dan kelas delegasi, dan dapat melakukan beberapa pemrosesan tambahan tanpa memodifikasi kode kelas delegasi. Keterbatasan proxy statis adalah bahwa Anda harus menulis kelas proxy sebelum berjalan. Mari kita fokus untuk memperkenalkan metode proxy dinamis untuk menghasilkan kelas proxy saat runtime.
2. Agen Dinamis
1. Apa itu proxy dinamis
Metode proxy yang dibuat oleh kelas proxy ketika program dijalankan disebut proxy dinamis. Artinya, dalam hal ini, kelas proxy tidak didefinisikan dalam kode Java, tetapi secara dinamis dihasilkan saat runtime berdasarkan "instruksi" kami dalam kode Java. Dibandingkan dengan proxy statis, keuntungan proxy dinamis adalah bahwa ia dapat dengan mudah menangani fungsi kelas proxy secara seragam tanpa memodifikasi fungsi dari setiap kelas proxy. Ini lebih abstrak. Mari kita gabungkan contoh untuk memperkenalkan bagaimana keunggulan proxy dinamis tercermin.
Sekarang, misalkan kita ingin menerapkan persyaratan: output "sebelum" sebelum menjalankan metode di kelas delegasi, dan output "setelah" setelah dieksekusi. Kami akan memperkenalkan kelas vendor sebagai kelas delegasi dalam contoh di atas, dan kelas bisnis sebagai kelas proxy. Pertama, mari kita gunakan proxy statis untuk mencapai persyaratan ini. Kode yang relevan adalah sebagai berikut:
Implement BusinessAgent kelas publik menjual {vendor private mvendor; Public BusinessAgent (vendor vendor) {this.mVendor = vendor; } public void sell () {System.out.println ("Sebelum"); mvendor.sell (); System.out.println ("After"); } public void ad () {System.out.println ("Sebelum"); mvendor.ad (); System.out.println ("After"); }} Dari kode di atas, kami dapat memahami bahwa menerapkan kebutuhan kami melalui proxy statis mengharuskan kami untuk menambahkan logika yang sesuai untuk setiap metode. Hanya ada dua metode di sini, jadi beban kerja tidak besar. Bagaimana jika antarmuka jual berisi ratusan metode? Pada saat ini, menggunakan proxy statis akan menulis banyak kode yang berlebihan. Dengan menggunakan proxy dinamis, kita dapat membuat "indikasi seragam" untuk memproses semua metode kelas proxy secara seragam tanpa memodifikasi setiap metode satu per satu. Mari kita perkenalkan cara menggunakan proxy dinamis untuk mengimplementasikan kebutuhan kita.
2. Gunakan proxy dinamis
(1) Saat menggunakan proxy dinamis di antarmuka InvocationHandler, kita perlu mendefinisikan kelas perantara yang terletak di antara kelas proxy dan kelas delegasi. Kelas perantara ini diperlukan untuk mengimplementasikan antarmuka InvocationHandler. Definisi antarmuka ini adalah sebagai berikut:
Invocation Handller {objek Invoke (Proxy Object, Metode Metode, Object [] args); } Dari nama InvocationHandler kita dapat mengetahui bahwa kelas mediasi yang mengimplementasikan antarmuka ini digunakan sebagai "prosesor panggilan". Ketika kami memanggil metode objek kelas proxy, "panggilan" ini akan diteruskan ke metode Invoke. Objek kelas proxy dilewatkan sebagai parameter proxy. Metode parameter mengidentifikasi metode mana yang kami sebut kelas proxy. Args adalah parameter dari metode ini. Dengan cara ini, panggilan kami ke semua metode di kelas proxy akan menjadi panggilan untuk memohon, sehingga kami dapat menambahkan logika pemrosesan terpadu ke metode Invoke (atau metode berbeda dari kelas proxy dapat diproses sesuai dengan parameter metode). Oleh karena itu, kita hanya perlu mengeluarkan "sebelum" dalam implementasi metode Invoke dari kelas mediasi, kemudian panggil metode Invoke dari kelas delegasi, dan kemudian output "setelah". Mari kita menerapkannya langkah demi langkah.
(2) Di bawah metode proxy dinamis kelas delegasi, kelas delegasi harus mengimplementasikan antarmuka tertentu. Di sini kami menerapkan antarmuka jual. Definisi kelas vendor adalah sebagai berikut:
Vendor kelas publik mengimplementasikan penjualan {public void sell () {System.out.println ("dalam metode jual"); } public void ad () {System, out.println ("Metode iklan")}} (3) Kelas Mediasi Seperti yang disebutkan di atas, kelas mediasi harus mengimplementasikan antarmuka InvocationHandler, karena prosesor panggilan "mencegat" panggilan ke metode kelas proxy. Definisi kelas perantara adalah sebagai berikut:
DynamicProxy kelas publik mengimplementasikan InvocationHandler {Private Object Obj; // OBJ adalah objek kelas delegasi; DynamicProxy publik (objek obj) {this.obj = obj; } @Override Public Object Invoke (Proxy Object, Metode Metode, Object [] args) melempar Throwable {System.out.println ("Sebelum"); Hasil Objek = Method.Invoke (OBJ, ARGS); System.out.println ("After"); hasil pengembalian; }} Dari kode di atas, kita dapat melihat bahwa kelas perantara memegang referensi objek delegasi, dan metode yang sesuai dari objek delegasi dipanggil dalam metode Invoke (baris 11). Apakah Anda pikir itu tampaknya akrab ketika Anda melihat ini? Memegang referensi objek delegasi melalui metode agregasi, pada akhirnya mengonversi semua panggilan eksternal untuk meminta panggilan ke objek delegasi. Bukankah ini metode implementasi proxy statis yang kami perkenalkan di atas? Faktanya, kelas perantara dan kelas delegasi membentuk hubungan proxy statis. Dalam hubungan ini, kelas perantara adalah kelas proxy, dan kelas delegasi adalah kelas delegasi; Kelas proxy dan kelas perantara juga membentuk hubungan proxy statis. Dalam hubungan ini, kelas perantara adalah kelas delegasi dan kelas proxy adalah kelas proxy. Dengan kata lain, hubungan proxy dinamis terdiri dari dua set hubungan proxy statis, yang merupakan prinsip proxy dinamis. Mari kita perkenalkan cara "menginstruksikan" secara dinamis menghasilkan kelas proxy.
(4) Kode proxy proxy proxy generasi dinamis Kode yang relevan adalah sebagai berikut:
kelas publik {public static void main (string [] args) {// Buat instance kelas mediasi DynamicProxy Inter = new DynamicProxy (new vendor ()); // Tambahkan kalimat ini akan menghasilkan file $ proxy0.class, yang merupakan sistem file kelas proxy yang dihasilkan secara dinamis.getProperties (). Put ("sun.misc.proxygenerator.saveGeneratedFiles", "true"); // Dapatkan instance kelas proxy jual jual jual = (sell) (proxy.newproxyInstance (sell.class.getClassLoader (), kelas baru [] {sell.class}, inter)); // Memanggil metode kelas proxy melalui objek kelas proxy akan benar -benar pergi ke metode Invoke untuk memanggil sell.sell (); sell.ad (); }} Dalam kode di atas, kami memanggil metode NewProxyInstance dari kelas proxy untuk mendapatkan instance kelas proxy. Kelas proxy ini mengimplementasikan antarmuka yang kami tentukan dan akan mendistribusikan panggilan metode ke prosesor panggilan yang ditentukan. Deklarasi metode ini adalah sebagai berikut:
Salin kode sebagai berikut: Objek Statis Publik NewProxyInstance (ClassLoader Loader, Class <?> [] Antarmuka, InvocationHandler H) Melempar IllegalArgumentException
Tiga parameter metode ini adalah sebagai berikut:
Loader: mendefinisikan classloder dari kelas proxy;
Antarmuka: Daftar antarmuka yang diimplementasikan oleh kelas proxy
H: Panggil prosesor, yaitu, instance kelas yang kami definisikan di atas yang mengimplementasikan antarmuka InvocationHandler, mari kita jalankan untuk melihat apakah proxy dinamis kami dapat bekerja dengan baik. Output yang saya jalankan di sini adalah:
Ini menunjukkan bahwa proxy dinamis kami memang berfungsi.
Kami telah secara singkat menyebutkan prinsip proxy dinamis di atas. Di sini kita akan meringkas secara singkat: Pertama, kita dapat memperoleh instance kelas proxy melalui metode newProxyInstance, dan kemudian kita dapat memanggil metode kelas proxy melalui instance kelas proxy ini. Dalam metode kelas proxy, kami benar -benar akan memanggil metode Invoke dari kelas mediasi (disebut prosesor). Dalam metode Invoke, kami memanggil metode yang sesuai dari kelas delegasi dan dapat menambahkan logika pemrosesan kami sendiri.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.