Sebelum mengetahui perbezaan di antara @Component, @Service, @Controller, dan @Repository annotations dalam Spring framework, adalah penting untuk kita memahami peranan @Component annotation dalam Spring.

Pada permulaan Spring, semua beans diisytiharkan dalam satu XML file. Ia agak berserabut dalam projek besar dan Spring mengetahui masalah ini. Pada versi seterusnya Spring memperkenalkan annotation-based dependency injection dan Java-based configuration.

Sejak Spring 2.5 annotation-based dependency injection diperkenalkan di mana Spring bean diimbas dan didaftarkan secara automatik menggunakan @Component annotation pada class.

Ini bermakna tidak perlu lagi isytiharkan bean menggunakan tag <bean> dan inject dependency, sebaliknya semuanya dilakukan secara automatik. Fungsi ini dihidupkan dan dimatikan menggunakan tag <context:component-scan>.

Apa @Service, @Controller, and @Repository annotation buat?

Mereka adalah bentuk khusus buat @Component annotation untuk situasi tertentu. Kita tak gunakan @Component untuk controller class dalam Spring MVC, sebaliknya kita guna @Controller yang lebih mudah difahami dan sesuai.

Menggunakan @Controller annotation kita lakukan dua benda iaitu kita isytiharkan class ini adalah sejenis Spring bean yang patut dijana dan diurus oleh Spring ApplicationContext, dan kita mengisytiharkan bahawa class ini adalah sejenis controller dalam setup MVC (yang akan digunakan oleh fungsi-fungsi dan tools khusus buat web).

Contohnya DispatcherServlet akan mencari @RequestMapping dalam classes yang ditandakan menggunakan @Controller tetapi tidak dalam @Component.

Ini bermakna @Component dan @Controller adalah sama untuk penghasilan bean dan dependency injection cuma @Controller adalah bentuk khusus buat @Component. Jika kita gantikan @Controller annotation dengan @Compoenent, Spring boleh kesan dan daftar controller class itu secara automatik tetapi ia takkan bekerja seperti yang diharapkan apabila berkaitan dengan request mapping.

Serupa juga dengan @Service annotation dan @Repository annotation, mereka adalah bentuk khusus @Component untuk service layer dan persistence layer. Spring bean dalam service layer patut ditandakan sebagai @Service bukannya @Component annotation dan spring bean dalam persistence layer patut ditandakan dengan @Repository annotation.

Menggunakan annotation khusus kita menyelam sambil minum air. Pertama, mereka akan dilayan sebagai Spring bean dan kedua kita boleh letak kelakuan khusus yang diperlukan oleh layer tersebut.

Contohnya @Repository tidak hanya membantu dalam tetapan berasaskan annotation tetapi juga akan menangkap Platform specific exceptions dan mencampak mereka sebagai satu Spring unchecked exception.

Kita juga harus umumkan org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor sebagai Spring bean dalam application context.

Bean post processor tersebut akan menambah advisor kepada semua bean yang ditandakan dengan @Repository supaya semua platform-specific exceptions ditangkap dan dicampak sebagai Spring unchecked data access exceptions.

Bagaimana Component Scanning berlaku dalam Spring?

Sejak Spring 2.0, Spring sediakan <context:component-scan> dan annotation-driven dependency injection untuk kesan dan daftar Spring bean tanpa perlu isytiharkan mereka dalam XML file.

Tetapi secara umumnya ia hanya kesan @Component dan tidak mencari @Controller, @Service dan @Repository. Mereka diimbas kerana mereka ditandakan sebagai @Component.

Cuba perhatikan pada definisi @Controller, @Service, dan @Repository annotation:

@Component
public @interface Service {
….
}

@Component
public @interface Repository {
….
}

@Component
public @interface Controller {

}

Jadi tidak salah untuk kita katakan bahawa @Controller, @Service, dan @Repository adalah jenis khusus daripada @Component annotation. <context:component-scan> akan kutip mereka dan daftar mereka sebagai beans sama seperti apabila mereka ditandakan sebagai @Component.

Mereka dikesan kerana mereka sendiri ditandakan dengan @Component annotation. Jika kita buat custom annotation dan tandakannya dengan @Component, ia juga akan dikesan oleh <context:component-scan>.

Boleh baca lebih lanjut mengenai dependency injection (suntikan kebergantungan), auto-wiring dan pelbagai bentuk konfigurasi dalam Spring seperti menggunakan XML based, annotation dan Java configuration.

 

Rumusan

Ini adalah rumusan mengenai @Component, @Service, @Controller, dan @Repository annotation dalam Spring Framework:

  1. @Component adalah stereotype umum untuk semua component atau bean yang diurus Spring. 
  2. @Repository adalah stereotype untuk persistence layer yang menguruskan capaian data.
  3. @Service adalah stereotype untuk service layer yang menyimpan business logic.
  4. @Controller adalah stereotype untuk presentation layer (Spring-MVC).

Secara ringkasnya: gunakan annotation paling sesuai berdasarkan layer yang diduduki oleh class tersebut.

Rujukan

  1. https://javarevisited.blogspot.com/2017/11/difference-between-component-service.html