Membandingkan Spring AOP dan AspectJ

1. Perkenalan

Ada beberapa perpustakaan AOP yang tersedia saat ini, dan ini harus dapat menjawab sejumlah pertanyaan:

  • Apakah ini kompatibel dengan aplikasi saya yang sudah ada atau yang baru?
  • Di mana saya dapat menerapkan AOP?
  • Seberapa cepat itu terintegrasi dengan aplikasi saya?
  • Apa overhead kinerja?

Pada artikel ini, kita akan melihat menjawab pertanyaan-pertanyaan ini dan memperkenalkan Spring AOP dan AspectJ - dua framework AOP paling populer untuk Java.

2. Konsep AOP

Sebelum kita mulai, mari kita lakukan tinjauan cepat tingkat tinggi atas istilah dan konsep inti:

  • Aspek - kode / fitur standar yang tersebar di beberapa tempat dalam aplikasi dan biasanya berbeda dari Logika Bisnis yang sebenarnya (misalnya, Manajemen transaksi). Setiap aspek berfokus pada fungsionalitas lintas sektor tertentu
  • Joinpoint - ini adalah titik tertentu selama eksekusi program seperti eksekusi metode, panggilan konstruktor, atau tugas lapangan
  • Saran - tindakan yang dilakukan oleh aspek dalam titik gabungan tertentu
  • Pointcut - ekspresi reguler yang cocok dengan titik gabungan. Setiap kali titik gabungan cocok dengan pemotongan poin, saran khusus yang terkait dengan pemotongan poin tersebut dijalankan
  • Menenun - proses menghubungkan aspek dengan objek yang ditargetkan untuk membuat objek yang disarankan

3. Spring AOP dan AspectJ

Sekarang, mari kita bahas Spring AOP dan AspectJ di sejumlah sumbu - seperti kapabilitas, tujuan, tenun, struktur internal, titik sambungan, dan kesederhanaan.

3.1. Kapabilitas dan Tujuan

Sederhananya, Spring AOP dan AspectJ memiliki tujuan yang berbeda.

Spring AOP bertujuan untuk menyediakan implementasi AOP sederhana di Spring IoC untuk memecahkan masalah paling umum yang dihadapi programmer. Ini tidak dimaksudkan sebagai solusi AOP lengkap - ini hanya dapat diterapkan pada biji yang dikelola oleh wadah Pegas.

Di sisi lain, AspectJ adalah teknologi AOP orisinal yang bertujuan untuk memberikan solusi AOP yang lengkap. Ini lebih kuat tetapi juga jauh lebih rumit daripada Spring AOP. Perlu juga dicatat bahwa AspectJ dapat diterapkan di semua objek domain.

3.2. Menenun

Baik AspectJ dan Spring AOP menggunakan jenis tenun berbeda yang memengaruhi perilaku mereka terkait kinerja dan kemudahan penggunaan.

AspectJ menggunakan tiga jenis tenun:

  1. Waktu kompilasi : Kompilator AspectJ mengambil kode sumber dari aspek dan aplikasi kita sebagai masukan dan menghasilkan file kelas anyaman sebagai keluaran
  2. Tenun pasca-kompilasi : Ini juga dikenal sebagai tenun biner. Ini digunakan untuk menenun file kelas dan file JAR yang ada dengan aspek kita
  3. Penenunan waktu muat : Ini persis seperti penenunan biner sebelumnya, dengan perbedaan bahwa penenunan ditunda hingga pemuat kelas memuat file kelas ke JVM

Untuk informasi lebih mendalam tentang AspectJ itu sendiri, baca artikel ini.

Karena AspectJ menggunakan tenun waktu kompilasi dan waktu muat kelas, Spring AOP memanfaatkan tenun runtime .

Dengan runtime weaving, aspek dijalin selama eksekusi aplikasi menggunakan proxy dari objek yang ditargetkan - menggunakan proxy dinamis JDK atau proxy CGLIB (yang akan dibahas di poin berikutnya):

3.3. Struktur dan Penerapan Internal

Spring AOP adalah kerangka kerja AOP berbasis proxy. Ini berarti bahwa untuk mengimplementasikan aspek ke objek target, itu akan membuat proxy dari objek itu. Ini dicapai dengan salah satu dari dua cara:

  1. Proksi dinamis JDK - cara yang disukai untuk Spring AOP. Setiap kali objek yang ditargetkan mengimplementasikan bahkan satu antarmuka, maka proxy dinamis JDK akan digunakan
  2. Proksi CGLIB - jika objek target tidak mengimplementasikan sebuah antarmuka, maka proksi CGLIB dapat digunakan

Kita dapat mempelajari lebih lanjut tentang mekanisme proxy AOP Spring dari dokumen resmi.

AspectJ, di sisi lain, tidak melakukan apa pun saat runtime karena class dikompilasi langsung dengan aspek.

Dan tidak seperti Spring AOP, ini tidak memerlukan pola desain apa pun. Untuk menjalin aspek kode, ia memperkenalkan kompilernya yang dikenal sebagai kompiler AspectJ (ajc), yang melaluinya kita mengkompilasi program kita dan kemudian menjalankannya dengan menyediakan pustaka runtime kecil (<100K).

3.4. Joinpoints

Pada bagian 3.3, kami menunjukkan bahwa Spring AOP didasarkan pada pola proxy. Karena itu, perlu membuat subkelas dari kelas Java yang ditargetkan dan menerapkan masalah lintas sektor yang sesuai.

Tapi itu datang dengan batasan. Kami tidak dapat menerapkan masalah (atau aspek) lintas sektor di seluruh kelas yang bersifat "final" karena tidak dapat diganti sehingga akan menghasilkan pengecualian waktu proses.

Hal yang sama berlaku untuk metode statis dan final. Aspek pegas tidak dapat diterapkan padanya karena tidak dapat diganti. Oleh karena itu Spring AOP karena keterbatasan ini, hanya mendukung titik gabungan eksekusi metode.

Namun, AspectJ merangkum masalah lintas bidang secara langsung ke dalam kode sebenarnya sebelum waktu proses. Tidak seperti Spring AOP, ia tidak perlu membuat subkelas objek yang ditargetkan dan dengan demikian mendukung banyak titik gabungan lainnya juga. Berikut adalah ringkasan dari titik penghubung yang didukung:

Joinpoint Spring AOP Didukung AspectJ Didukung
Metode Panggilan Tidak Iya
Eksekusi Metode Iya Iya
Panggilan Konstruktor Tidak Iya
Eksekusi Pembuat Tidak Iya
Eksekusi penginisialisasi statis Tidak Iya
Inisialisasi objek Tidak Iya
Referensi lapangan Tidak Iya
Penugasan lapangan Tidak Iya
Eksekusi penangan Tidak Iya
Eksekusi nasihat Tidak Iya

Perlu juga dicatat bahwa di Spring AOP, aspek tidak diterapkan ke metode yang dipanggil dalam kelas yang sama.

Itu jelas karena ketika kita memanggil metode dalam kelas yang sama, maka kita tidak memanggil metode proxy yang disediakan Spring AOP. Jika kita membutuhkan fungsionalitas ini, maka kita harus mendefinisikan metode terpisah dalam kacang yang berbeda, atau menggunakan AspectJ.

3.5. Kesederhanaan

Spring AOP jelas lebih sederhana karena tidak memperkenalkan compiler atau penenun tambahan di antara proses build kami. Ini menggunakan tenun runtime, dan oleh karena itu terintegrasi secara mulus dengan proses build biasa kami. Meskipun terlihat sederhana, ini hanya berfungsi dengan kacang yang dikelola oleh Spring.

Namun, untuk menggunakan AspectJ, kami harus memperkenalkan compiler AspectJ (ajc) dan mengemas ulang semua library kami (kecuali kami beralih ke post-compile atau load-time weaving).

Ini, tentu saja, lebih rumit daripada yang sebelumnya - karena ini memperkenalkan Java Tools AspectJ (yang menyertakan kompiler (ajc), debugger (ajdb), generator dokumentasi (ajdoc), browser struktur program (ajbrowser)) yang kami perlu diintegrasikan dengan IDE kami atau fitur build.

3.6. Performa

Sejauh menyangkut kinerja, tenun waktu kompilasi jauh lebih cepat daripada tenun waktu proses . Spring AOP adalah framework berbasis proxy, jadi ada pembuatan proxy pada saat aplikasi dimulai. Selain itu, ada beberapa pemanggilan metode lagi per aspek, yang memengaruhi kinerja secara negatif.

Di sisi lain, AspectJ menjalin aspek ke dalam kode utama sebelum aplikasi dijalankan dan dengan demikian tidak ada overhead waktu proses tambahan, tidak seperti Spring AOP.

Untuk alasan ini, tolok ukur menunjukkan bahwa AspectJ hampir 8 hingga 35 kali lebih cepat daripada Spring AOP.

4. Ringkasan

Tabel singkat ini merangkum perbedaan utama antara Spring AOP dan AspectJ:

Musim semi AOP AspekJ
Diimplementasikan di Java murni Diimplementasikan menggunakan ekstensi bahasa pemrograman Java
Tidak perlu proses kompilasi terpisah Membutuhkan kompiler AspectJ (ajc) kecuali LTW disiapkan
Hanya tenun runtime yang tersedia Tenun runtime tidak tersedia. Mendukung waktu kompilasi, pasca-kompilasi, dan waktu muat Weaving
Kurang Kuat - hanya mendukung penenunan tingkat metode Lebih Kuat - dapat menenun bidang, metode, konstruktor, penginisialisasi statis, kelas / metode akhir, dll ...
Hanya dapat diimplementasikan pada biji yang dikelola oleh wadah Spring Dapat diterapkan di semua objek domain
Hanya mendukung jalan pintas eksekusi metode Mendukung semua cara pintas
Proksi dibuat dari objek yang ditargetkan, dan aspek diterapkan pada proksi ini Aspek dijalin langsung ke dalam kode sebelum aplikasi dijalankan (sebelum runtime)
Jauh lebih lambat dari AspectJ Performa Lebih Baik
Mudah dipelajari dan diterapkan Relatif lebih rumit dari Spring AOP

5. Memilih Framework yang Tepat

Jika kita menganalisis semua argumen yang dibuat di bagian ini, kita akan mulai memahami bahwa sama sekali tidak satu framework lebih baik dari yang lain.

Sederhananya, pilihan sangat bergantung pada persyaratan kami:

  • Framework: Jika aplikasinya tidak menggunakan framework Spring, maka kami tidak punya pilihan selain membatalkan ide menggunakan Spring AOP karena tidak dapat mengelola apa pun yang berada di luar jangkauan wadah pegas. Namun, jika aplikasi kita dibuat seluruhnya menggunakan framework Spring, maka kita dapat menggunakan Spring AOP karena mudah dipelajari dan diterapkan.
  • Fleksibilitas: Mengingat dukungan joinpoint terbatas, Spring AOP bukanlah solusi AOP lengkap, tetapi memecahkan masalah paling umum yang dihadapi programmer. Meskipun jika kita ingin menggali lebih dalam dan mengeksploitasi AOP secara maksimal dan menginginkan dukungan dari berbagai titik sambungan yang tersedia, maka AspectJ adalah pilihannya.
  • Kinerja: Jika kami menggunakan aspek terbatas, maka ada perbedaan kinerja yang sepele. Namun terkadang ada kasus ketika aplikasi memiliki lebih dari puluhan ribu aspek. Kami tidak ingin menggunakan tenun runtime dalam kasus seperti itu, jadi akan lebih baik untuk memilih AspectJ. AspectJ dikenal 8 hingga 35 kali lebih cepat dari Spring AOP
  • Yang Terbaik dari Keduanya: Kedua kerangka kerja ini sepenuhnya kompatibel satu sama lain. Kami selalu dapat memanfaatkan Spring AOP bila memungkinkan dan masih menggunakan AspectJ untuk mendapatkan dukungan dari titik penghubung yang tidak didukung oleh yang sebelumnya.

6. Kesimpulan

Dalam artikel ini, kami menganalisis Spring AOP dan AspectJ, di beberapa area utama.

Kami membandingkan dua pendekatan ke AOP baik dalam hal fleksibilitas maupun pada seberapa mudah keduanya sesuai dengan aplikasi kami.