Pemindaian Komponen Musim Semi

1. Ikhtisar

Dalam tutorial ini, kami akan membahas pemindaian komponen di Spring. Saat bekerja dengan Spring, kami dapat membuat anotasi kelas kami untuk menjadikannya kacang Spring. Tapi, selain itu, kita dapat memberi tahu Spring tempat mencari kelas beranotasi ini karena tidak semuanya harus menjadi kacang dalam proses khusus ini.

Tentu saja, ada beberapa standar untuk pemindaian komponen tetapi kami juga dapat menyesuaikan paket untuk pencarian.

Pertama, mari kita lihat pengaturan default.

2. @ComponentScan Tanpa Argumen

2.1. Menggunakan @ComponentScan di Aplikasi Musim Semi

Dengan Spring, kami menggunakan anotasi @ComponentScan bersama dengan anotasi @Configuration untuk menentukan paket yang ingin dipindai . @ComponentScan tanpa argumen memberi tahu Spring untuk memindai paket saat ini dan semua sub-paketnya.

Katakanlah kita memiliki @Configuration berikut di com.baeldung.componentscan.springapp paket:

@Configuration @ComponentScan public class SpringComponentScanApp { private static ApplicationContext applicationContext; @Bean public ExampleBean exampleBean() { return new ExampleBean(); } public static void main(String[] args) { applicationContext = new AnnotationConfigApplicationContext(SpringComponentScanApp.class); for (String beanName : applicationContext.getBeanDefinitionNames()) { System.out.println(beanName); } } }

Juga, katakanlah kita memiliki komponen Kucing dan Anjing dalam paket com.baeldung.componentscan.springapp.animals :

package com.baeldung.componentscan.springapp.animals; // ... @Component public class Cat {}
package com.baeldung.componentscan.springapp.animals; // ... @Component public class Dog {}

Dan terakhir, kami memiliki komponen Rose di paket com.baeldung.componentscan.springapp.flowers :

package com.baeldung.componentscan.springapp.flowers; // ... @Component public class Rose {}

Output dari metode main () akan berisi semua kacang paket com.baeldung.componentscan.springapp dan sub-paketnya:

springComponentScanApp cat dog rose exampleBean

Perhatikan bahwa kelas aplikasi utama juga berupa kacang karena dianotasi dengan @Configuration, yang merupakan @Component .

Juga, perhatikan bahwa kelas aplikasi utama dan kelas konfigurasi tidak harus sama. Jika berbeda, tidak masalah di mana harus meletakkan kelas aplikasi utama. Hanya lokasi kelas konfigurasi yang penting karena pemindaian komponen dimulai dari paketnya secara default .

Terakhir, perhatikan bahwa dalam contoh kami @ComponentScan setara dengan:

@ComponentScan(basePackages = "com.baeldung.componentscan.springapp")

di mana argumen basePackages adalah paket atau larik paket untuk dipindai.

2.2. Menggunakan @ComponentScan dalam Aplikasi Spring Boot

Trik dengan Spring Boot adalah banyak hal terjadi secara implisit. Kami menggunakan anotasi @SpringBootApplication , tetapi itu hanya kombinasi dari tiga anotasi:

@Configuration @EnableAutoConfiguration @ComponentScan

Mari buat struktur serupa di paket com.baeldung.componentscan.springbootapp . Kali ini aplikasi utamanya adalah:

package com.baeldung.componentscan.springbootapp; // ... @SpringBootApplication public class SpringBootComponentScanApp { private static ApplicationContext applicationContext; @Bean public ExampleBean exampleBean() { return new ExampleBean(); } public static void main(String[] args) { applicationContext = SpringApplication.run(SpringBootComponentScanApp.class, args); checkBeansPresence( "cat", "dog", "rose", "exampleBean", "springBootComponentScanApp"); } private static void checkBeansPresence(String... beans) { for (String beanName : beans) { System.out.println("Is " + beanName + " in ApplicationContext: " + applicationContext.containsBean(beanName)); } } }

Semua paket dan kelas lainnya tetap sama, kami hanya akan menyalinnya ke paket com.baeldung.componentscan.springbootapp terdekat .

Spring Boot memindai paket yang mirip dengan contoh kami sebelumnya. Mari kita periksa hasilnya:

Is cat in ApplicationContext: true Is dog in ApplicationContext: true Is rose in ApplicationContext: true Is exampleBean in ApplicationContext: true Is springBootComponentScanApp in ApplicationContext: true

Alasan kami hanya memeriksa keberadaan biji dalam contoh kedua kami (sebagai lawan mencetak semua biji), adalah karena hasilnya akan terlalu besar.

Ini karena anotasi implisit @EnableAutoConfiguration yang membuat Spring Boot membuat banyak kacang secara otomatis, bergantung pada dependensi dalam file pom.xml .

3. @ComponentScan Dengan Argumen

Sekarang mari kita sesuaikan jalur untuk pemindaian. Misalnya, kita ingin mengecualikan kacang mawar .

3.1. @ComponentScan untuk Paket Tertentu

Kami dapat melakukannya dengan beberapa cara. Pertama, kita dapat mengubah paket dasar:

@ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals") @Configuration public class SpringComponentScanApp {   // ... }

Sekarang hasilnya adalah:

springComponentScanApp cat dog exampleBean

Mari kita lihat ada apa di balik ini:

  • springComponentScanApp dibuat sebagai konfigurasi yang diteruskan sebagai argumen ke AnnotationConfigApplicationContext
  • exampleBean adalah kacang yang dikonfigurasi di dalam konfigurasi
  • kucing dan anjing ada dalam paket com.baeldung.componentscan.springapp.animals yang ditentukan

Semua kustomisasi yang tercantum di atas juga berlaku di Spring Boot. Kita bisa menggunakan @ComponentScan bersama dengan @SpringBootApplication dan hasilnya akan sama:

@SpringBootApplication @ComponentScan(basePackages = "com.baeldung.componentscan.springbootapp.animals")

3.2. @ComponentScan dengan Pengecualian

Cara lain adalah dengan menggunakan filter, menentukan pola kelas yang akan dikecualikan:

@ComponentScan(excludeFilters = @ComponentScan.Filter(type=FilterType.REGEX, pattern="com\\.baeldung\\.componentscan\\.springapp\\.flowers\\..*"))

Kami juga dapat memilih jenis filter yang berbeda, karena anotasi mendukung beberapa opsi fleksibel untuk memfilter kelas yang dipindai :

@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Rose.class))

4. Paket Default

Kita harus menghindari menempatkan kelas @Configuration dalam paket default (yaitu dengan tidak menentukan paket sama sekali). Dalam kasus ini, Spring memindai semua kelas di semua toples di jalur kelas. Itu menyebabkan kesalahan dan aplikasi mungkin tidak dapat dimulai.

5. Kesimpulan

Di artikel ini, kami telah mempelajari paket mana yang dipindai Spring secara default dan cara menyesuaikan jalur ini.

Seperti biasa, kode lengkap tersedia di GitHub.