Proxy dinamis sebenarnya adalah kelas java.lang.reflect.Proxy yang secara dinamis menghasilkan byte kelas berdasarkan semua antarmuka yang Anda tentukan. Kelas ini akan mewarisi kelas Proxy dan mengimplementasikan semua antarmuka yang Anda tentukan (array antarmuka yang Anda lewati dalam parameter ) ; Kemudian gunakan classloader yang Anda tentukan untuk memuat byte kelas ke dalam sistem, dan terakhir buat objek dari kelas tersebut, dan inisialisasi beberapa nilai objek, seperti invocationHandler, yang merupakan anggota Metode yang sesuai dengan semua antarmuka . Setelah inisialisasi, objek dikembalikan ke klien pemanggil. Dengan cara ini, yang didapat klien adalah objek Proxy yang mengimplementasikan semua antarmuka Anda. Silakan lihat contoh analisisnya:
antarmuka publik BusinessProcessor {
proses kekosongan publikBisnis();
}
@Mengesampingkan
proses kekosongan publikBisnis() {
System.out.println("bisnis pemrosesan....");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
*Kategori agen bisnis
* @penulis fanhadoop
*
*/
kelas publik BusinessProcessorHandler mengimplementasikan InvocationHandler {
target Objek pribadi = null;
BusinessProcessorHandler(Target objek) {
this.target = sasaran;
}
pemanggilan Objek publik (Proksi objek, Metode metode, Objek[] args)
lemparan Dapat dilempar {
Sistem.keluar
.println("Anda dapat melakukan sesuatu di sini sebelum memproses bisnis Anda");
Hasil objek = metode.invoke(target, args);
Sistem.keluar
.println("Anda dapat melakukan sesuatu di sini setelah memproses bisnis Anda");
hasil pengembalian;
}
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
Tes kelas publik {
/**
* @param argumen
*/
public static void main(String[] args) {
BusinessProcessorImpl bimpl = BusinessProcessorImpl baru();
Pengendali BusinessProcessorHandler = BusinessProcessorHandler baru(bpimpl);
BusinessProcessor bp = (BusinessProcessor) Proxy.newProxyInstance(
bimpl.getClass().getClassLoader(), bimpl.getClass()
.getInterfaces(), pengendali);
bp.prosesBisnis();
Sistem.keluar.println(bp.getClass().getName());
printClassDefinition(bp.getClass());
}
getModifier String statis publik(pengubah int) {
Hasil string = "";
saklar (pengubah) {
Pengubah kasus.PRIVATE:
hasil = "pribadi";
Pengubah kasus.PUBLIC:
hasil = "publik";
Pengubah kasus. DILINDUNGI:
hasil = "dilindungi";
Pengubah Kasus. ABSTRAK:
hasil = "abstrak";
Pengubah kasus. AKHIR:
hasil = "akhir";
Pengubah kasus. ASLI:
hasil = "asli";
Pengubah kasus.STATIS:
hasil = "statis";
Pengubah kasus. DISINKRONISASI:
hasil = "disinkronkan";
Pengubah kasus. KETAT:
hasil = "ketat";
Pengubah kasus. TRANSIEN:
hasil = "sementara";
Pengubah kasus.VOLATILE:
hasil = "volatil";
Pengubah kasus. ANTARMUKA:
hasil = "antarmuka";
}
hasil pengembalian;
}
public static void printClassDefinition(Kelas clz) {
String clzModifier = getModifier(clz.getModifiers());
if (clzModifier != null && !clzModifier.equals("")) {
clzModifier = clzModifier + " ";
}
String superClz = clz.getSuperclass().getName();
if (superClz != null && !superClz.equals("")) {
superClz = "meluas " + superClz;
}
Kelas[] antarmuka = clz.getInterfaces();
String inter = "";
for (int i = 0; i < antarmuka.panjang; i++) {
jika (saya == 0) {
inters += "implementasi ";
}
inters += antarmuka[i].getName();
}
Sistem.keluar.println(clzModifier + clz.getName() + " " + superClz + " "
+ antar);
Sistem.keluar.println("{");
Bidang[] bidang = clz.getDeclaredFields();
for (int i = 0; i < bidang.panjang; i++) {
Pengubah string = getModifier(fields[i].getModifiers());
if (pengubah != null && !pengubah.sama dengan("")) {
pengubah = pengubah + " ";
}
String fieldName = bidang[i].getName();
String fieldType = bidang[i].getType().getName();
System.out.println(" " + pengubah + fieldType + " " + fieldName
+ ";");
}
Sistem.keluar.println();
Metode[] metode = clz.getDeclaredMethods();
for (int i = 0; i < metode.panjang; i++) {
Metode metode = metode[i];
Pengubah string = getModifier(method.getModifiers());
if (pengubah != null && !pengubah.sama dengan("")) {
pengubah = pengubah + " ";
}
String metodeNama = metode.getName();
Kelas returnClz = metode.getReturnType();
String retrunType = returnClz.getName();
Kelas[] clzs = metode.getParameterTypes();
String paraList = "(";
for (int j = 0; j < clzs.length; j++) {
paraList += clzs[j].getName();
if (j != clzs.panjang - 1) {
paraList += ", ";
}
}
paraList += ")";
clzs = metode.getExceptionTypes();
Pengecualian string = "";
for (int j = 0; j < clzs.length; j++) {
jika (j == 0) {
pengecualian += "melempar ";
}
pengecualian += clzs[j].getName();
if (j != clzs.panjang - 1) {
pengecualian += ", ";
}
}
pengecualian += ";";
String metodePrototipe = pengubah + retrunType + " " + Nama metode
+ paraList + pengecualian;
System.out.println(" " + metodePrototipe);
}
Sistem.keluar.println("}");
}
}
boolean sama dengan (java.lang.Object);
java.lang.String toString();
int kode hash();
batal prosesBisnis();
}
Jelasnya, metode Proxy.newProxyInstance akan melakukan hal-hal berikut:
1. Menghasilkan kelas secara dinamis berdasarkan antarmuka parameter kedua yang diteruskan untuk mengimplementasikan antarmuka dalam antarmuka. Dalam contoh ini, ini adalah metode processBusiness dari antarmuka BusinessProcessor. Dan itu mewarisi kelas Proxy dan menulis ulang tiga metode seperti kode hash, toString, dan sama dengan. Untuk implementasi spesifik, lihat ProxyGenerator.generateProxyClass(...); Dalam contoh ini, kelas $Proxy0 dibuat
2. Muat kelas yang baru dibuat ke dalam jvm melalui parameter pertama yang diteruskan, classloder. Akan memuat kelas $Proxy0
3. Gunakan parameter ketiga untuk memanggil konstruktor $Proxy0 (InvocationHandler) dari $Proxy0 untuk membuat objek $Proxy0, dan gunakan parameter antarmuka untuk menelusuri semua metode antarmukanya dan menghasilkan objek Metode untuk menginisialisasi beberapa variabel anggota Metode dari obyek.
4. Kembalikan instance $Proxy0 ke klien.
Tidak apa-apa sekarang. Mari kita lihat bagaimana klien menyesuaikannya dan itu akan menjadi jelas.
1. Klien mendapatkan objek instance $Proxy0. Karena $Proxy0 mewarisi BusinessProcessor, tidak ada masalah dalam mengonversinya menjadi BusinessProcessor.
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
2. bp.prosesBisnis();
Yang sebenarnya disebut adalah $Proxy0.processBusiness(); maka implementasi $Proxy0.processBusiness() adalah memanggil metode invoke melalui InvocationHandler!