Mekanisme refleksi Java dan proxy dinamis membuat Java lebih kuat. Konsep inti Spring IOC dan AOP diimplementasikan melalui mekanisme refleksi dan proxy dinamis.
1 Refleksi Java
Contoh:
Pengguna pengguna = pengguna baru (); user.settime5flag ("test"); Class <?> Cls = class.forname ("com.test.user"); // Antarmuka harus publik, terlepas dari apakah itu digunakan secara internal di kelas ini! Baik menggunakan cls.getDeclaredMethod (), atau melintasi untuk memodifikasi metode aksesibilitas = cls.getmethod ("getTime5flag"); String res1 = (string) method.invoke (user); System.out.println (res1); // Jika Anda melibatkan tipe dasar seperti int, gunakan int.class! Integer.class! = Int.class! metode = cls.getMethod ("setTime5flag", string.class); method.invoke (pengguna, "rollen"); metode = cls.getmethod ("getTime5flag"); String res2 = (string) method.invoke (user); System.out.println (res2);Dapatkan paket lengkap dan nama kelas melalui suatu objek:
user.getClass (). getName (); // nama kelas penuh nama user.getclass (). getsImplename (); // nama kelas tanpa nama paket
Dapatkan Kelas:
Class.forname ("com.test.user"); com.test.user.class; user.getClass (); Instantiate objek melalui kelasPengguna pengguna = (pengguna) cls.newinstance (); // Harus ada konstruktor parameterDapatkan semua konstruktor
Konstruktor <?> Cons [] = cls.getConstructors (); // return cons [0] .newinstance () dalam urutan deklarasi; // Tidak ada deklarasi tampilan, maka ada konstruktor defaultDapatkan semua antarmuka yang diimplementasikan oleh suatu kelas
Kelas <?> intes [] = cls.getInterfaces ();Dapatkan Kelas Orang Tua
cls.getsuperclass ();Dapatkan pengubahnya
int mo = cls.getModifiers (); int mo = cons [0] .getModifiers (); int mo = method.getModifiers (); Modifier.tostring (Mo);Dapatkan parameter metode
method.getParameters (); cons [0] .getParameters ();Dapatkan Jenis Parameter Metode
method.getParametorpes (); cons [0] .getParametorpes ();Dapatkan semua jenis pengecualian yang dilemparkan dengan deklarasi metode
method.getExceptionTypes ();Dapatkan semua properti yang dinyatakan di kelas ini
Bidang [] field = cls.getDeclaredFields (); // Sertakan privatefield [0] .getModifiers (); bidang [0] .getType ();
Dapatkan semua atribut publik dari kelas ini, termasuk deklarasi kelas induk, deklarasi antarmuka, dan semua atribut publik dari deklarasi kelas ini
cls.getFields ();
Atur atribut yang ditentukan ke akses
field.setAccessible (true); field.set (obj, 'ces'); field.get (obj);
* Perbedaan antara getFields () dan getDeclaredFields (): getFields () hanya dapat mengakses bidang yang dinyatakan sebagai publik di kelas. Itu tidak dapat mengakses bidang pribadi dan dapat mengakses bidang publik yang diwarisi dari kelas lain. getDeclaredFields () dapat mengakses semua bidang di kelas, yang tidak ada hubungannya dengan publik, pribadi, dan melindungi, tetapi tidak dapat mengakses bidang yang diwarisi dari kelas lain.
* Perbedaan antara getMethods () dan getDeclaredMethods (): getMethods () hanya dapat mengakses metode yang dinyatakan sebagai publik di kelas, dan metode pribadi tidak dapat diakses, dan dapat mengakses metode publik yang diwarisi dari kelas lain; GetDeclaredMethods () dapat mengakses semua bidang di kelas, yang tidak ada hubungannya dengan publik, pribadi, dan melindungi, dan tidak dapat mengakses metode yang diwarisi dari kelas lain.
* Perbedaan antara getConstructors () dan getDeclaredConstructors (): getConstructors () hanya dapat mengakses konstruktor yang dinyatakan sebagai publik di kelas; GetDeclaredConstructors () dapat mengakses semua konstruktor di kelas, dan tidak ada hubungannya dengan publik, pribadi, dan melindungi.
Dapatkan dan ubah informasi array melalui refleksi
int [] temp = {1,2,3,4,5}; class <?> demo = temp.getClass (). getComponentType (); System.out.println ("Tipe Array:"+Demo.getName ()); // intsystem.out.println ("array panjang:) "+Array.getLength (temp)); // 5system.out.println (" Elemen pertama dari array: "+array.get (temp, 0)); // 1Array.set (Temp, 0, 100); System.out.println (" Elemen pertama dari array setelah modifikasi adalah: "+array. Dapatkan Jenis Arraycls.getComponentType ();Tentukan apakah itu jenis array
cls.isarray ();
2 Agen Java
Model proxy adalah model desain Java yang umum digunakan. Karakteristiknya adalah bahwa kelas proxy dan kelas delegasi memiliki antarmuka yang sama. Kelas proxy terutama bertanggung jawab untuk preprocessing pesan, memfilter pesan, meneruskan pesan ke kelas delegasi, dan memproses pesan setelah acara. Biasanya ada hubungan antara kelas proxy dan kelas delegasi. Objek kelas proxy dikaitkan dengan objek kelas delegasi. Objek kelas proxy itu sendiri tidak benar -benar menerapkan layanan, tetapi menyediakan layanan spesifik dengan memanggil metode yang relevan dari objek kelas delegasi.
Menurut periode penciptaan agen, kelas agen dapat dibagi menjadi dua jenis.
• Proxy statis: Dibuat oleh pemrogram atau secara otomatis menghasilkan kode sumber dengan alat tertentu dan kemudian mengkompilasinya. Sebelum program berjalan, file .class dari kelas proxy sudah ada.
• Dinamis Proxy: Saat program berjalan, bytecode secara dinamis dihasilkan oleh mekanisme refleksi Java.
2.1 proxy statis
Public Interface Count {public void queryCount ();} countImpl kelas publik mengimplementasikan jumlah {public void queryCount () {System.out.println ("Lihat metode akun ..."); }} // kelas proxy class countproxy mengimplementasikan jumlah {countimpl private countimpl; public countproxy (countimpl countImpl) {this.countImpl = countImpl; } @Override public void queryCount () {System.out.println ("Sebelum pemrosesan transaksi"); countimpl.querycount (); // Panggil metode kelas delegasi; System.out.println ("Setelah pemrosesan transaksi"); }} // test kelas public class testCount {public static void main (string [] args) {countImppl countImpl = countImpl baru (); Countproxy countproxy = countproxy baru (countimpl); countproxy.querycount (); }}Amati kode dan temukan bahwa setiap kelas proxy hanya dapat melayani satu antarmuka, sehingga terlalu banyak proxy pasti akan terjadi dalam pengembangan program. Selain itu, semua operasi proxy kecuali untuk berbagai metode panggilan, semua operasi lain sama, sehingga kode harus diulangi saat ini. Cara terbaik untuk menyelesaikan masalah ini adalah dengan menyelesaikan semua fungsi proxy melalui kelas proxy, jadi harus dilakukan dengan menggunakan proxy dinamis saat ini.
2.2 Agen Dinamis
Bytecode kelas proxy dinamis secara dinamis dihasilkan oleh mekanisme refleksi Java ketika program dijalankan, tanpa perlu pemrogram untuk menulis kode sumbernya secara manual. Kelas proxy dinamis tidak hanya menyederhanakan pemrograman tetapi juga meningkatkan skalabilitas sistem perangkat lunak, karena mekanisme refleksi Java dapat menghasilkan semua jenis kelas proxy dinamis.
2.2.1 JDK Dynamic Proxy
Kelas proxy dan antarmuka InvocationHandler di paket java.lang.reflect menyediakan kemampuan untuk menghasilkan kelas proxy dinamis.
Antarmuka InvocationHandler:
Invocation Invocation Handler {
Invoke Objek Publik (Proxy Objek, Metode Metode, Objek [] args) melempar yang dapat dilempar;
}
Deskripsi Parameter:
Proxy Objek: Mengacu pada objek yang sedang diproksi.
Metode metode: metode yang akan dipanggil
Objek [] args: parameter yang diperlukan saat memanggil metode
Anda dapat memikirkan subkelas antarmuka InvocationHandler sebagai kelas operasi akhir dari proxy, menggantikan proxysubject.
Kelas proxy:
Kelas proxy adalah kelas operasi yang berspesialisasi dalam proxy. Ini dapat secara dinamis menghasilkan kelas implementasi untuk satu atau lebih antarmuka melalui kelas ini. Kelas ini menyediakan metode operasi berikut:
Objek statis publik newProxyInstance (classloader loader, class <?> [] antarmuka, InvocationHandler h) melempar ilegalargumentException
Deskripsi Parameter:
Classloader loader: class loader
Kelas <?> [] Antarmuka: Dapatkan semua antarmuka
InvocationHandler H: Dapatkan Instance Subclass dari InvocationHandler Interface
Jika Anda ingin menyelesaikan proxy dinamis, pertama -tama Anda harus mendefinisikan subkelas antarmuka InvocationHandler untuk menyelesaikan operasi spesifik proxy.
Subjek antarmuka {public string mengatakan (nama string, int usia);} kelas realsubject mengimplementasikan subjek {@Override public string mengatakan (nama string, int usia) {return name + "" + usia; }} // JDK Dynamic Proxy Class MyInVocationHandler mengimplementasikan InvocationHandler {private objek target = null; // ikat objek delegasi dan kembalikan bik objek publik kelas proxy (target objek) {this. target = target; return proxy.newproxyInstance (target.getClass (). getClassLoader (), target.getClass (). getInterfaces (), this); // ikat antarmuka (CGLIB menebus untuk ini)} @Override Objek publik Invoke (objek proxy, metode metode, objek [] args) melempar lempar {system.out.println ("sebelum metode!"); Objek temp = method.invoke (target, args); System.out.println ("After Method!"); kembalikan suhu; }} class hello {public static void main (string [] args) {myInvocationHandler demo = myInvocationHandler baru (); Subjek sub = (subjek) demo.bind (new realsubject ()); Info string = sub.say ("rollen", 20); System.out.println (info); }} Namun, proxy dinamis JDK bergantung pada implementasi antarmuka. Jika beberapa kelas tidak menerapkan antarmuka, mereka tidak dapat menggunakan proxy JDK, sehingga mereka perlu menggunakan proxy dinamis CGLIB.
2.2.2 Proxy Dinamis CGlib
Mekanisme proxy dinamis JDK hanya dapat proxy kelas yang mengimplementasikan antarmuka, sementara kelas yang tidak mengimplementasikan antarmuka tidak dapat mengimplementasikan proxy dinamis JDK.
CGLIB mengimplementasikan proxy untuk kelas. Prinsipnya adalah untuk menghasilkan subkelas untuk kelas target yang ditentukan dan mengesampingkan peningkatan implementasi metode. Namun, karena warisan digunakan, kelas akhir yang dimodifikasi tidak dapat diproksi.
Public Interface Bookfacade {public void addBook (); } public class bookfacadeImpl1 {public void addBook () {System.out.println ("Metode biasa untuk menambahkan buku ..."); }} import java.lang.reflect.method; impor net.sf.cglib.proxy.enhancer; impor net.sf.cglib.proxy.methodInterceptor; impor net.sf.cglib.proxy.methodproxy; // CGLIB Dynamic Proxy Class Public Class Bookfacadecglib mengimplementasikan MethodInterceptor {Private Object Target; // ikat objek delegasi dan kembalikan objek publik kelas proxy getInstance (objek target) {this.target = target; Penambah penambah = penambah baru (); Enhancer.setsuperclass (this.target.getClass ()); // Callback Method Enhancer.setCallback (ini); // Buat penambah pengembalian objek proxy.create (); } @Override // Callback Metode Intercept Objek Publik (Objek OBJ, Metode Metode, Objek [] args, MethodProxy Proxy) melempar Throwable {System.out.println ("Function Start"); Objek temp = proxy.invokesuper (obj, args); System.out.println ("Function End"); kembalikan suhu; }} kelas publik testcglib {public static void main (string [] args) {bookfacadecglib cglib = bookfacadecglib baru (); BookfacadeImpl1 bookcglib = (bookfacadeImpl1) cglib.getInstance (bookfacadeImpl1 ()); bookcglib.addbook (); }}Diskusi singkat di atas tentang refleksi dan proxy Java adalah semua konten yang saya bagikan dengan Anda. Saya harap Anda dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.