Jangan menyalahgunakan bidang pribadi dapatkan / ditetapkan oleh refleksi
Menggunakan refleksi seperti yang dilakukan dalam beberapa jawaban di sini adalah sesuatu yang bisa kita hindari.
Ini membawa nilai kecil di sini sementara itu menyajikan beberapa kelemahan:
- kami mendeteksi masalah refleksi hanya saat runtime (mis: bidang tidak ada lagi)
- Kami ingin enkapsulasi tetapi bukan kelas buram yang menyembunyikan dependensi yang harus terlihat dan membuat kelas lebih buram dan kurang teruji.
- itu mendorong desain yang buruk. Hari ini Anda mendeklarasikan a
@Value String field
. Besok Anda dapat mendeklarasikan 5
atau 10
tentang mereka di kelas itu dan Anda bahkan mungkin tidak langsung sadar bahwa Anda mengurangi desain kelas tersebut. Dengan pendekatan yang lebih terlihat untuk mengatur bidang-bidang ini (seperti konstruktor), Anda akan berpikir dua kali sebelum menambahkan semua bidang ini dan Anda mungkin akan merangkumnya ke dalam kelas lain dan digunakan @ConfigurationProperties
.
Jadikan kelas Anda dapat diuji baik secara kesatuan maupun dalam integrasi
Untuk dapat menulis kedua tes unit biasa (yang tanpa wadah pegas berjalan) dan tes integrasi untuk kelas komponen Pegas Anda, Anda harus membuat kelas ini dapat digunakan dengan atau tanpa Pegas.
Menjalankan wadah dalam unit test ketika tidak diperlukan adalah praktik buruk yang memperlambat pembangunan lokal: Anda tidak menginginkannya.
Saya menambahkan jawaban ini karena sepertinya tidak ada jawaban di sini yang menunjukkan perbedaan ini dan karena itu mereka mengandalkan wadah yang berjalan secara sistematis.
Jadi saya pikir Anda harus memindahkan properti ini didefinisikan sebagai internal kelas:
@Component
public class Foo{
@Value("${property.value}") private String property;
//...
}
ke dalam parameter konstruktor yang akan disuntikkan oleh Spring:
@Component
public class Foo{
private String property;
public Foo(@Value("${property.value}") String property){
this.property = property;
}
//...
}
Contoh uji unit
Anda dapat instantiate Foo
tanpa Spring dan menyuntikkan nilai apa pun untuk property
terima kasih kepada konstruktor:
public class FooTest{
Foo foo = new Foo("dummyValue");
@Test
public void doThat(){
...
}
}
Contoh uji integrasi
Anda dapat menyuntikkan properti dalam konteks dengan Spring Boot dengan cara sederhana ini berkat properties
atribut @SpringBootTest
:
@SpringBootTest(properties="property.value=dummyValue")
public class FooTest{
@Autowired
Foo foo;
@Test
public void doThat(){
...
}
}
Anda dapat menggunakan sebagai alternatif @TestPropertySource
tetapi menambahkan anotasi tambahan:
@SpringBootTest
@TestPropertySource("property.value=dummyValue")
public class FooTest{ ...}
Dengan Spring (tanpa Spring Boot), itu seharusnya menjadi sedikit lebih rumit tetapi karena saya tidak menggunakan Spring tanpa Spring Boot sejak lama, saya tidak suka mengatakan hal yang bodoh.
Sebagai catatan: jika Anda memiliki banyak @Value
bidang untuk diset, mengekstraknya ke dalam kelas yang diberi penjelasan @ConfigurationProperties
lebih relevan karena kami tidak ingin konstruktor dengan terlalu banyak argumen.