Pendahuluan

Proxy Pattern merupakan salah satu konsep utama dalam proses managing Bean dalam framework Spring ketika dihadapkan pada kasus AOP (Aspect Oriented Programming).

Maksud AOP (Aspect Oriented Programming) disini adalah ketika kita menambahkan fitur tambahan terhadap class/object yang kita punya, tapi tanpa mengubah code aplikasi kita secara langsung.

Caranya biasanya dengan membuat class/object baru yang memfasilitasi fitur khusus tersebut.

Misalnya :

  • Menambahkan fitur transaksi database terhadap insert, update, delete data.
  • Menambahkan fitur caching di sebuah method kita.
  • Menambakan fitur retry terhadap sebuah method yang kita duga mempunyai kemungkinan bisa nggak kepanggil karena sesuatu hal, sehingga perlu kita call berulang2 sampai kepanggil.
  • dll.

Semua hal diatas biasanya tidak kita masukkan dalam logicnya aplikasi kita.

Akan tetapi biasanya menggunakan Anotasi yang nanti dihandle oleh library lainnya.

Istilah lainnya, kita menempatkan sebuah Aspect tambahan di atas logic aplikasi kita.

Misalnya :

  • @Retryable
  • @Cacheable
  • @Transactional
  • @Async
  • @Aspect
  • dan anotasi lain berbasis AOP (Aspect Oriented Programming)

Semua anotasi diatas sebenarnya menggunakan fitur AOP (Aspect Oriented Programming)

Dan fitur AOP di Spring Framework ini, menggunakan konsep Proxy Pattern.

Memahami mekanisme Proxy Pattern di code aplikasi kita yang memakai Spring Framework, akan memudahkan kita dalam menganalisa kesalahan mendasar ketika menggunakan anotasi-anotasi tambahan diatas.


Kenapa jadi penting ??


Karena banyak kasus penggunaan Anotasi-anotasi diatas, tetapi karena ketidak tahuan kita mengenai konsep Proxy Pattern nya Spring Framework, maka tidak akan error di waktu compile/build, ketika kita salah menempatkan lokasi anotasi-anotasi tersebut.

Akan tetapi tiba-tiba waktu dijalankan pada saat Runtime, maka fitur dari Anotasi diatas tidak jalan.

Misalnya :

  • @Retryable , tidak melakukan proses Retry, padahal tidak ada kompilasi yang error.
  • @Cacheable , tidak melakukan proses Caching terhadap method yang dipanggil, padahal tidak ada kompilasi yang error.
  • @Async , tidak melakukan proses Asynchronous terhadap method yang dipanggil, padahal tidak ada kompilasi yang error.
  • dll.

Biasanya hal ini dikarenakan satu hal :

Method yang kita tempatkan anotasi diatas tersebut, ditaruh di class yang sama dengan class pemanggilnya.

Loh kok bisa ?

Coba kita lihat penjelasan mengenai Proxy Pattern sbb :


Proxy Pattern

Proxy Pattern merupakan salah satu Structural Design Pattern yang diusulkan oleh Gang Of Four sebagai salah satu Design Pattern yang cocok untuk kasus :

  • Kalau kita perlu melakukan kontrol terhadap sebuah class/objek tertentu, tanpa si pemanggil class/object tersebut tahu.
  • Kita perlu melakukan sebuah aksi sebelum atau sesudahnya ketika class/object tertentu tersebut dipanggil.

Spring Proxy Pattern


Ketika Spring AOP digunakan di sebuah class (kalau pakai Anotasi-anotasi diatas), maka secara otomatis Spring Framework akan membuat sebuah Proxy untuk class tersebut.

Dengan class Proxy ini, maka Spring dapat melakukan Inject sebelum dan/atau sesudah pemanggilan method dari class aslinya.

Sesuai dengan konsep Proxy Pattern, maka Proxy class ini hanya berlaku ketika pemanggilan method di sebuah class dilakukan dari class lain yang berbeda.

Ketika pemanggilan dilakukan oleh object/class yang sama, maka secara internal, pemanggilan method class tersebut tidak melalui Proxy class, akan tetapi melalui referensi internal yaitu referensi this.

Yang biasa kita temui kalau membuat setter/getter POJO di sebuah class.

Referensi this tersebut tidak melibatkan Proxy, yang berakibat fungsi AOP di Spring tidak berjalan.

Hal ini biasanya menjadi kesalahan umum dari Software Engineer Java ketika menambahkan anotasi AOP sbb :

  • @Retryable
  • @Cacheable
  • @Transactional
  • @Async
  • @Aspect
  • dan anotasi lain berbasis AOP (Aspect Oriented Programming)

yaitu biasanya :

Method yang kita tempatkan anotasi diatas tersebut, ditaruh di class yang sama dengan class pemanggilnya.

Solusinya


Solusinya sederhana, yaitu :

Pindahkan method yang memakai anotasi AOP tersebut, ke file/class yang berbeda dengan code pemanggilnya.

Itu saja !