1. Pendahuluan
Selama proses pengembangan, kita sering perlu menulis banyak contoh:
@GetMapping ("/id/get") hasil publik getById (string id) melempar pengecualian {log.info ("Parameter permintaan adalah:"+id); Verifikasi (verifyparam baru ("ID departemen", id)); Hasil Hasil = Hasil Baru ("berhasil diperoleh melalui ID!", Service.QueryById (ID)); log.info ("pesan pengembalian adalah:"+result.toString ()); hasil pengembalian; }Cetak parameter permintaan dan parameter pengembalian, dan operasi ini ada di setiap metode, membuat kode kami lebih berlebihan. Untuk alasan ini, kita dapat menggunakan proxy dinamis untuk menggunakan parameter cetak dan mencetak pesan pengembalian sebagai bagian, dan menggunakan ekspresi titik-potong untuk memotongnya ke dalam setiap metode.
2. Langkah
1. Memperkenalkan dependensi terkait AOP:
<!-Ketergantungan yang berhubungan dengan AOP-> <dependency> <GroupId> org.springframework.boot </groupid> <ArTifactId> Spring-boot-starter-aop </artifactid> </dependency>
Setelah memperkenalkan dependensi, Spring-AOP akan memuat dependensi yang dibutuhkan. Spring menggunakan aspek secara default untuk mengimplementasikan pemberitahuan.
Di antara mereka, AspectJweaver.jar berisi file yang menganalisis ekspresi titik-potong aspek. Ketergantungan ini juga diperlukan saat menggunakan ekspresi titik-potong untuk menangani transaksi.
2. Konfigurasi:
1) Buat kelas konfigurasi:
/*** @Function Deskripsi: Kelas AOP yang digunakan untuk operasi lapisan pengontrol* @Author Administrator*/ @Component // Handle Objects to Spring for Management @Aspect // Representasikan kelas ini sebagai kelas aspek Controlleraop {}Anotasi @Aspect menyatakan bahwa itu adalah kelas manajemen aspek, di mana ekspresi titik-potong dapat didefinisikan, dan kerangka kerja AspectJ akan menguraikannya.
2) Tentukan ekspresi titik-potong:
@Pointcut ("Eksekusi (publik*com.hzt.manage.*. Web.controller ..*.*(..))") // pointcut ekspresi public void privilege () {}Di mana @pointcut mewakili metode ini sebagai ekspresi titik-potong. Nilainya adalah ekspresi titik-potong, di mana nilainya dapat dihilangkan dan format kasarnya adalah:
@Annotation (tag ekspresi + format ekspresi)
Untuk format tersebut, indikator-indikator titik-potong aspek yang didukung oleh Spring AOP adalah sebagai berikut:
1. Eksekusi: Titik koneksi yang digunakan untuk mencocokkan eksekusi metode;
2. Di dalam: digunakan untuk mencocokkan pelaksanaan metode dalam jenis yang ditentukan;
3. Ini: metode eksekusi yang digunakan untuk mencocokkan tipe objek proxy AOP saat ini; Perhatikan bahwa pencocokan jenis objek proxy AOP, yang mungkin termasuk memperkenalkan antarmuka dan pencocokan jenis;
4. Target: Metode eksekusi yang digunakan untuk mencocokkan jenis objek target saat ini; Perhatikan bahwa pencocokan tipe objek target adalah pencocokan tipe, sehingga pengenalan antarmuka tidak termasuk;
5. Args: Metode eksekusi digunakan untuk mencocokkan parameter yang dilewati dengan metode yang saat ini dieksekusi sebagai jenis yang ditentukan;
6. @within: Digunakan untuk mencocokkan sehingga menahan metode dalam jenis anotasi yang ditentukan;
7. @target: Metode eksekusi yang digunakan untuk mencocokkan jenis objek target saat ini, di mana objek target memegang anotasi yang ditentukan;
8. @Args: Digunakan untuk mencocokkan eksekusi parameter yang disahkan dalam metode yang saat ini dieksekusi yang memiliki anotasi yang ditentukan;
9. @Annotation: Digunakan untuk mencocokkan metode yang saat ini mengeksekusi metode ini memiliki anotasi yang ditentukan;
10. Bean: Spring AOP Extension, AspectJ tidak memiliki metode eksekusi untuk mencocokkan objek kacang dengan nama tertentu;
11. Referensi PointCut: Berarti mengacu pada titik masuk penamaan lainnya, hanya gaya @apectj yang mendukungnya, tetapi bukan gaya skema.
Args mendefinisikan parameter saat mengeksekusi metode ekspresi titik-potong:
@Pointcut (value = "Eksekusi (publik*com.hzt.manage.*. Web.controller ..*.*(..)) && args (param)", argnames = "param") // pointcut ekspresi public void privilege1 (string param) {}Kami fokus pada ekspresi titik koneksi metode eksekusi, dan struktur kasarnya adalah:
eksekusi (pengubah-pola? Ret-tipe-pola-pola-pola-pola-pola-pola (param-pola) lemparan-pola?)
1. Pencocokan pengubah (pola pengubah?) (Dapat dihilangkan)
2. Pencocokan Nilai Pengembalian (RET-Type-Pattern) dapat mewakili nilai pengembalian untuk *, seperti (String) hanya mewakili memfilter titik masuk yang mengembalikan jenis string, nama kelas dari jalur lengkap, dll. (Tidak dapat dihilangkan)
3. Deklarasikan-Pola-Pola? Misalnya, *.Manage mewakili paket tingkat pertama sebagai arbitrer dan paket tingkat kedua sebagai nama Kelola. *.. Kelola mewakili paket subkelas di bawah semua paket mengelola. com .. *. Comtroller mewakili semua paket pengontrol di bawah paket COM, dll., Dan * berarti semua paket cocok. (Tidak dihilangkan)
4. Metode pencocokan nama (pola nama) dapat menentukan nama metode atau * mewakili semua, get * mewakili semua metode yang dimulai dengan get, atau Anda dapat menentukan awalan * get mewakili metode apa pun dengan akhiran sewenang-wenang (tidak dihilangkan)
5. Pencocokan parameter ((param-pola)) dapat menentukan jenis parameter tertentu, beberapa parameter dipisahkan oleh "," dan setiap parameter juga dapat "*" untuk mencocokkan semua jenis parameter, seperti (string) berarti metode untuk mencocokkan parameter string; (*, String) berarti metode untuk mencocokkan dua parameter, parameter pertama dapat berupa jenis apa pun, dan parameter kedua adalah jenis string; (..) dapat digunakan untuk mewakili parameter apa pun (tidak dihilangkan)
6. Pencocokan tipe pengecualian (pola lemparan?)
3. Tentukan metode facet
@Around ("Privilege ()") Objek Publik sekitar (ProsidingJoInpoint pjd) melempar Throwable {// Dapatkan Metode Nama String ClassName = pjd.getSignature (). GetClass (). GetName (); // Dapatkan nama metode eksekusi string methodName = pjd.getSignature (). GetName (); / ** Pencetakan Log Inisialisasi*/ Logger Log = LoggerFactory.GetLogger (className); // Tentukan hasil objek parameter pengembalian = null; // Catat waktu mulai lama start = System.currentTimeMillis (); // Dapatkan Objek Parameter Metode [] args = pjd.getArgs (); String params = "Parameter permintaan front-end adalah:"; // Dapatkan koleksi parameter permintaan dan lintasan dan splice untuk (objek objek: args) {params + = object.toString () + ","; } params = params.substring (0, params.length () - 1); // cetak parameter permintaan parameter log.info (classname + "class" + methodName + "" + params); // Jalankan hasil metode target = pjd.proed (); // cetak pesan pengembalian log.info ("Metode mengembalikan pesan sebagai:" + (hasil hasil dari hasil? (Hasil) Hasil: hasil)); // Dapatkan Log.info waktu eksekusi (MethodName + "Waktu eksekusi metode adalah:" + (System.CurrentTimeMillis () - start)); hasil pengembalian; }5. @around Notifikasi surround, seperti yang ditunjukkan pada kode di atas, itu adalah pemberitahuan surround, yang memiliki parameter ProcePingJoinPoint
Di mana pjd.proed (); Metode mewakili pelaksanaan metode target dan mendapatkan nilai pengembalian jenis objek. Kami dapat memproses nilai pengembalian, seperti pemrosesan dekorasi, dll.
Nilai pengembalian adalah hasil dari eksekusi metode. Dalam kode di atas, pertama -tama memperoleh nama kelas, nama metode, parameter permintaan metode, dll., Melakukan pencetakan splicing, dan merekam waktu mulai dari eksekusi metode, dan mencetaknya ke log.
Kemudian jalankan metode, dapatkan hasil pengembalian metode, cetak waktu eksekusi dan hasil eksekusi.
Akhirnya, hasil eksekusi dikembalikan. Artinya, pengkodean bagian AOP dari pesan permintaan dan pesan pengembalian selesai.
Di mana @around mewakili itu sebagai metode pemberitahuan sekitarnya, ia memiliki tipe berikut:
1. @Before pra-notifikasi, yang memiliki parameter permintaan, yang digunakan untuk menghubungkan detail koneksi dari titik koneksi saat ini, umumnya termasuk nama metode dan nilai parameter. Badan metode dijalankan sebelum metode dijalankan, dan parameter metode tidak dapat diubah, atau hasil eksekusi metode tidak dapat diubah.
@Before (value = "privilege ()") public void Sebelumnya (joinpoint goinpoint) {}2. @After Post Notification: Pemberitahuan bahwa eksekusi dilakukan terlepas dari apakah pengecualian terjadi setelah metode target dieksekusi. Dalam pasca-notifikasi, hasil eksekusi dari metode target tidak dapat diakses (karena pengecualian dapat terjadi), dan hasil eksekusi dari metode tersebut tidak dapat diubah.
@Before (value = "privilege ()") public void After (joinpoint goinpoint) {}3. @Afterreturning mengembalikan pemberitahuan. Pemberitahuan yang dieksekusi hanya ketika metode target dieksekusi sama dengan metode pasca-diatur. Ini dapat mengakses hasil eksekusi metode (karena eksekusi normal) dan detail koneksi metode, tetapi tidak dapat mengubah hasil eksekusi metode.
@AfterReturning (value = "privilege ()") public void afterReturning (joinpoint goinpoint, hasil objek) {}Nilai pengembalian yang disimpan dalam hasil adalah metode.
4. @AfterThrowing Pemberitahuan Pengecualian: Kode yang akan dieksekusi hanya ketika pengecualian terjadi dalam metode target. Atribut lemparan mewakili pengecualian yang dilemparkan selama pelaksanaan badan metode, dan nilainya harus konsisten dengan nilai pengecualian dalam metode.
@AfterThrowing (value = "privilege ()", throwing = "ex") public void Exceed (joinpoint goinpoint, pengecualian ex) {}3. Tes
Tulis metode pengontrol
@Restcontroller@requestMapping ("/API/V1/DEPT") Public Class DeptController memperluas Basecontroller {/** Kelas Pencatatan*/Log Logger Privat = LoggerFactory.GetLogger (getClass ()); / ** Layanan saya sendiri*/ @Autowired Private Deptservice Service; /*** @function Deskripsi: Metode untuk permintaan departemen Konten berdasarkan ID* @Return Dept*/@getMapping ("/id/get") hasil publik getById (ID String) melempar pengecualian {verify (verifyparam baru ("id departemen", id)); mengembalikan hasil baru ("berhasil diperoleh melalui id!", service.querybyid (id)); }}Dengan cara ini, metode di lapisan pengontrol kami sangat ringkas.
Hasil tes:
2018-04-10 22: 59: 27.468 Info 1460 --- [NIO-8088-EXEC-5] nProTedingjoinpoint $ MethodyignatureImpl: Parameter permintaan ujung front-end GetByID adalah: 22
2018-04-10 22:59:27.470 INFO 1460 --- [nio-8088-exec-5] nProceedingJoinPoint$MethodSignatureImpl: The method returns the message as:Result [result_code=suc, result_message=Successfully obtained department information through id!, data=Dept [id=22, no=22, name=22, manager=22, description=22, phone=22, createtime = thu 19 Apr 23:38:37 CST 2018, editTime = null]]
2018-04-10 22: 59: 27.470 Info 1460 --- [NIO-8088-EXEC-5] nProedingingjoinpoint $ MethodyignatureImpl: Waktu eksekusi metode getByID adalah: 2
Ini memungkinkan Anda untuk mencetak parameter permintaan, hasil pengembalian, waktu eksekusi, dll. Dengan pencetakan yang elegan, ringkas, dan ringkas!