Mempersiapkan Sertifikasi Spring Profesional. Wadah, IOC, Kacang

Selamat siang, Habr.


Hari ini saya memutuskan untuk menyajikan kepada Anda terjemahan dari serangkaian artikel dalam persiapan untuk Sertifikasi Profesional Spring .


Terjemahan ini hanya artikel pertama, jika ditujukan kepada audiens, saya akan terus menerbitkan terjemahan.


Mengapa saya melakukan ini, karena sudah ada banyak bahan khusus?
  1. Seringkali informasi di dalamnya tidak terstruktur, tidak dikumpulkan, atau tidak relevan
  2. Pengembang muda mungkin tidak tahu bahasa Inggris. Siklus ini dapat digunakan tidak hanya untuk sertifikasi, tetapi juga untuk pelatihan diri / pengulangan materi.
  3. Bahan-bahan ini dapat digunakan dalam persiapan untuk wawancara, seperti mereka diatur dalam bentuk pertanyaan dan jawaban.
  4. Keuntungan penting, dan paling penting, QA ini dibuat dari pertanyaan dari Panduan Studi Penting resmi.

  • Saya sengaja melewatkan beberapa pertanyaan yang menurut saya berlebihan atau yang tidak ada dalam panduan .

Daftar isi
  1. Ketergantungan injeksi, wadah, IOC, kacang
  2. AOP (pemrograman berorientasi aspek)
  3. JDBC, Transaksi, JPA, Data Musim Semi
  4. Boot musim semi
  5. Musim semi mvc
  6. Keamanan musim semi
  7. SISA
  8. Pengujian


Saya akan menulis daftar sumber dari mana penulis mengambil materi
  • Pola desain pegas 5
  • Spring in Action edisi ke-4
  • Keamanan Musim Semi - Edisi Ketiga
  • Sertifikasi Core Spring 5 secara Detail oleh Ivan Krizsan
  • Dokumentasi Pegas dan API Spring API

Jadi, mari kita mulai.


Apa itu injeksi ketergantungan (DI) dan apa manfaatnya?

Ketergantungan injeksi adalah pola khusus yang mengurangi komunikasi antara komponen Pegas. Jadi, ketika menerapkan DI, kode Anda menjadi lebih bersih, lebih sederhana, menjadi lebih mudah dipahami dan diuji.
Menurut pola DI, membuat objek untuk dependensi ditransfer ke pabrik atau diberikan kepada pihak ketiga. Ini artinya kita bisa fokus menggunakan benda-benda ini daripada membuatnya.


Manfaat DI
  • Mengurangi komunikasi antar bagian aplikasi
  • Peningkatan pengujian
  • Arsitektur Aplikasi yang Disempurnakan
  • Mengurangi kode boilerplate
  • Membakukan pengembangan aplikasi

Mengapa antarmuka direkomendasikan untuk membuat kacang Spring?
  • Peningkatan pengujian. Dalam pengujian, kacang dapat diganti dengan objek khusus (tiruan atau rintisan) yang mengimplementasikan antarmuka kacang.
  • Memungkinkan Anda menggunakan mekanisme proxy dinamis dari JDK (misalnya, saat membuat repositori melalui Spring Data)
  • Memungkinkan Anda menyembunyikan implementasinya

Apa itu konteks aplikasi?

Dalam Spring Framework, antarmuka org.springframework.factory.BeanFactory menyediakan pabrik org.springframework.factory.BeanFactory , yang pada saat yang sama merupakan wadah aplikasi IoC. Manajemen bean didasarkan pada konfigurasi (java atau xml).


Antarmuka org.springframework.context.ApplicationContext adalah pembungkus atas pabrik kacang yang menyediakan beberapa fitur tambahan, seperti AOP, transaksi, keamanan, i18n, dll.


Apa itu wadah dan apa siklus hidupnya?

Dasar dari Kerangka Pegas adalah sebuah wadah, dan objek kami "hidup" dalam wadah ini.
Wadah biasanya menciptakan banyak objek berdasarkan konfigurasi mereka dan mengelola siklus hidup mereka dari membuat objek hingga kehancuran.


Wadah adalah objek yang mengimplementasikan antarmuka ApplicationContext .


Siklus hidup kontainer
  1. Wadah dibuat saat aplikasi dimulai.
  2. Wadah membaca data konfigurasi
  3. Deskripsi tempat sampah dibuat dari data konfigurasi
  4. BeanFactoryPostProcessors menangani deskripsi bean
  5. Wadah tersebut membuat kacang menggunakan deskripsi mereka
  6. Kacang diinisialisasi - nilai properti dan dependensi tertanam dalam kacang
  7. BeanPostProcessor memulai metode panggilan balik
  8. Aplikasi aktif dan berjalan
  9. Penutupan aplikasi diinisialisasi
  10. Wadah ditutup
  11. Metode panggilan balik disebut

Bagaimana cara membuat instance ApplicationContext?

Spring menyediakan beberapa variasi konteks.


Ada beberapa implementasi dasar antarmuka ApplicationContext:


  • FileSystemXmlApplicationContext
  • ClassPathXmlApplicationContext
  • AnnotationConfigApplicationContext
  • XmlWebApplicationContext
  • AnnotationConfigWebApplicationContext

Contoh membuat konteks:


 ApplicationContext ctx = new FileSystemXmlApplicationContext(                                     "c:/bean_properties.xml"); ApplicationContext ctx = new AnnotationConfigApplicationContext(                            "com.springdemoapp.JavaConfig.class"); 

Bisakah Anda menggambarkan siklus hidup kacang dalam wadah?
  1. Memuat deskripsi nampan, membuat grafik dependensi (antara kacang)
  2. Membuat dan BeanFactoryPostProcessors
  3. Buat Kacang
  4. Spring menyuntikkan nilai dan dependensi ke dalam properti kacang
  5. Jika kacang mengimplementasikan metode setBeanName() dari antarmuka NameBeanAware, maka kacang ID diteruskan ke metode
  6. Jika kacang mengimplementasikan BeanFactoryAware, maka Spring membuat referensi ke pabrik kacang melalui setBeanFactory() dari antarmuka ini.
  7. Jika kacang mengimplementasikan antarmuka ApplicationContextAware, maka Spring membuat referensi ke ApplicationContext melalui setApplicationContext() .
  8. BeanPostProcessor adalah antarmuka khusus (tentangnya di bawah ini), dan Spring memungkinkan tempat sampah untuk mengimplementasikan antarmuka ini. Dengan menerapkan metode postProcessBeforeInitialization() , Anda dapat mengubah instance bean sebelum menginisialisasi (bean) (menyetel properti, dll.)
  9. Jika metode panggilan balik didefinisikan, maka Spring memanggil mereka. Sebagai contoh, ini adalah metode yang dianotasikan oleh @PostConstruct atau metode initMethod dari anotasi @Bean .
  10. Kacang sekarang siap digunakan. Itu dapat diperoleh dengan menggunakan metode ApplicationContext#getBean() .
  11. Setelah konteks ditutup ( close() metode dari ApplicationContext), kacang hancur.
  12. Jika kacang memiliki metode yang dijelaskan oleh @PreDestroy , maka metode ini akan dipanggil sebelum kehancuran. Jika kacang mengimplementasikan DisposibleBean, maka Spring akan memanggil metode destroy() untuk menghapus sumber daya atau mematikan proses dalam aplikasi. Jika metode @Bean didefinisikan dalam destroyMethod , maka itu juga disebut.

Bagaimana cara mendapatkan ApplicationContext dalam tes integrasi?

Jika Anda menggunakan JUnit 5, maka Anda harus menentukan 2 anotasi:


  • @ExtendWith (TestClass.class) - digunakan untuk menunjukkan kelas uji
  • @ContextConfoguration (classes = JavaConfig.class) - memuat konfigurasi java / xml untuk membuat konteks dalam pengujian

Anda dapat menggunakan anotasi @SpringJUnitConfig , yang menggabungkan kedua anotasi ini.
Anda dapat menggunakan anotasi @SpringJUnitWebConfig untuk menguji lapisan web.


Bagaimana cara mematikan konteks dalam suatu aplikasi?

Jika ini bukan aplikasi web, maka ada 2 cara:


  • Daftarkan shutdown-hook menggunakan pemanggilan metode registerShutdownHook() , itu juga diimplementasikan dalam kelas AbstractApplicationContext. Ini adalah metode yang disukai.
  • Anda dapat memanggil metode close() dari kelas AbstractApplicationContext.

Dalam aplikasi Spring Boot:


  • Spring Boot akan mendaftarkan hook shutdown untuk Anda sendiri.

Apa itu konfigurasi Java? Bagaimana ini diterapkan?

Untuk membuat kelas dengan konfigurasi berdasarkan kode Java, Anda perlu memberikan anotasi dengan
@Configuration .
Kelas ini akan berisi metode pabrik untuk membuat kacang dalam wadah.
Metode-metode ini harus dijelaskan dengan penjelasan @Bean .


Contoh:


 @Configuration public class DSConfig {  @Bean  public DataSource dataSource() {      return DataSourceBuilder          .create()          .username("")          .password("")          .url("")          .driverClassName("")          .build();  } } 

Kelas ini akan menempatkan instance kelas DataSource dalam wadah. Nantinya dapat digunakan saat mengakses database.


DI menggunakan anotasi, pemindaian kelas

Pemindaian komponen - Pegas secara otomatis mendeteksi kacang yang ada di wadah. Ini adalah tempat sampah dengan anotasi-stereotip.


Namun, pemindaian komponen tidak diaktifkan secara default.
Untuk mengaktifkan pemindaian, anotasi kelas @ Konfigurasi dengan anotasi @ComponentScanning . Spring akan secara otomatis memindai paket yang berisi kelas ini dan semua sub-paketnya.
Anda dapat menentukan paket lain untuk pemindaian, dan bahkan kelas:


 // 2  @Configuration(basePackages = {"soundsystem", "video"}) 

 //  @Configuration(basePackageClasses = "MyClass.class") 

Autowiring - Pegas akan secara otomatis menyuntikkan dependensi saat memindai atau menempatkan nampan di dalam wadah.
Ketergantungan injeksi menggunakan anotasi @Autowire .


Apa itu stereotip (anotasi-stereotip)?

Stereotip adalah penjelasan yang menunjukkan fungsi khusus.
Semua stereotip termasuk anotasi @Component .


KomponenAnotasi root yang menandai kelas sebagai kandidat untuk implementasi otomatis
PengendaliMenunjukkan bahwa kelas adalah pengontrol untuk mengirim data ke depan.
@RestControllerMenunjukkan bahwa kelas adalah pengontrol untuk REST.
Berisi anotasi Controller dan @ResponseBody
LayananMenunjukkan bahwa kelas adalah layanan untuk mengeksekusi logika bisnis.
RepositoriMenunjukkan bahwa kelas adalah repositori untuk bekerja dengan database.
@ KonfigurasiMenunjukkan bahwa kelas berisi konfigurasi Java (metode @ Bean)

Apa cakupan bin? Apa visibilitas default mereka?

Lingkup - ruang lingkup. Ada 2 cakupan default.


Singleton
Lingkup default. Hanya ada 1 contoh kacang dalam wadah
Prototipe
Sejumlah instance bin dapat berada di wadah

Dan 4 cakupan dalam aplikasi web.


Minta
Cakupan - 1 permintaan HTTP. Kacang baru dibuat untuk setiap permintaan.
Sesi
Lingkup - 1 sesi. Kacang baru dibuat untuk setiap sesi.
Aplikasi
Lingkup - Siklus Hidup ServletContext
Soket web
Lingkup - Siklus Hidup WebSocket

Lingkup ditunjukkan menggunakan penjelasan @Bean pada metode @Bean .


Bagaimana berbagai cakupan dan multithreading terkait?

Prototipe Lingkup tidak aman karena thread itu tidak menjamin bahwa instance yang sama akan dipanggil hanya dalam 1 utas.


Singleton Scope, di sisi lain, aman dari benang.


Bagaimana kacang dibuat: secara instan atau malas? Bagaimana cara mengubah perilaku ini?

Kacang singleton biasanya dibuat segera setelah pemindaian.
Kacang prototipe biasanya dibuat hanya atas permintaan.


Anda dapat menggunakan anotasi @Lazy untuk mengindikasikan cara menginisialisasi.
Itu ditempatkan pada metode @ Bean, pada kelas @ konfigurasi, atau pada kelas @ komponen.
Bergantung pada parameter (benar atau salah) yang diterima oleh anotasi, inisialisasi akan menjadi malas atau akan segera terjadi. Secara default (mis., Tanpa menentukan parameter), true digunakan.


Apa yang terjadi jika sebuah bin dengan satu ruang lingkup tertanam dalam sebuah bin dengan ruang lingkup lain?

Kacang singleton dapat ditanam di kacang lainnya.


Hanya prototype atau singleton dapat tertanam dalam singleton .
Jika Anda menerapkan prototipe, maka prototipe unik akan dibuat untuk setiap singleton.


Prototipe dapat menjadi ketergantungan bagi kacang apa pun.
Anda hanya dapat mengimplementasikan singleton atau prototipe.


Apa itu BeanFactoryPostProcessor dan kapan itu digunakan?
  • BeanFactoryPostProcessor berfungsi pada deskripsi bin atau metadata konfigurasi sebelum bin dibuat.
  • Spring menyediakan beberapa implementasi BeanFactoryPostProcessor berguna, misalnya, membaca file properti dan mendapatkan properti BeanFactoryPostProcessor dari mereka.
  • Anda dapat menulis implementasi BFPP Anda sendiri.

Mengapa Anda memerlukan metode @ Bean statis?

Untuk menggunakan BFPP khusus. Anda dapat mengganti mekanisme untuk mendapatkan data dari metafile.


 @Bean public static PropertySourcesPlaceholderConfigurer pspc() {    //,    pspc } 

Jelaskan properti anotasi @Bean
  • destroyMethod - menunjuk ke metode panggilan balik. Metode ini di tempat sampah.
  • initMethod - menunjuk ke metode panggilan balik. Metode ini di tempat sampah.
  • name - nama kacang. Secara default, nama kacang adalah nama metode.
  • value - alias untuk nama ()

Apa itu BeanPostProcessor dan apa bedanya dengan BeanFactoryPostProcessor?

Spring menggunakan beberapa BeanPostProcessors.
Misalnya, CommonAnnotationPostProcessor atau AutowiredAnnotationBeanPostProcessor .
BPP bekerja dengan instance kacang, mis. wadah membuat tempat sampah, dan kemudian BPP dimulai.



Apa itu metode panggilan balik dan bagaimana menggunakannya?

Ada 3 opsi untuk membuat metode tersebut:


  • @PreDestroy dan penjelasan @PostConstruct
  • destroyMethod dan destroyMethod dalam penjelasan destroyMethod mengarah ke metode di kelas bean
  • InitializingBean#afterPropertiesSet() dan DisposableBean#destroy() . Untuk mengganti metode ini, Anda perlu mengimplementasikan antarmuka yang sesuai.


Bagaimana saya bisa menggunakan anotasi @ Autowire dan apa perbedaannya?

Berikut ini adalah jenis DI yang dapat digunakan dalam aplikasi Anda:


  • Konstruktor DI
  • Setter di
  • Bidang di

DI melalui konstruktor dianggap sebagai cara terbaik, karena baginya tidak perlu menggunakan refleksi, dan juga dia tidak memiliki kelemahan DI melalui setter.
DI melalui bidang tidak dianjurkan, karena Untuk ini, refleksi digunakan yang mengurangi produktivitas.
DI melalui konstruktor dapat menyebabkan dependensi melingkar . Untuk menghindari hal ini, Anda dapat menggunakan inisialisasi malas bean atau DI melalui setter.


Jelaskan perilaku anotasi @Autowired
  1. Wadah menentukan jenis objek yang akan ditanam.
  2. Wadah mencari kacang dalam konteks (alias wadah) yang cocok dengan jenis yang diinginkan
  3. Jika ada beberapa kandidat, dan salah satunya ditandai sebagai @Primary , maka itu akan diterapkan
  4. Jika penjelasan @Autowire + Qualifier digunakan, wadah akan menggunakan informasi dari @Qualifier untuk mengetahui komponen mana yang akan digunakan
  5. Jika tidak, wadah akan berusaha menyuntikkan komponen berdasarkan nama atau ID-nya.
  6. Jika tidak ada metode yang berhasil, pengecualian akan dilemparkan

Wadah menangani DI menggunakan AutowiredAnnotationBeanPostProcessor . Dalam hal ini, anotasi tidak dapat digunakan di BeanFactoryPP atau BeanPP.


Jika objek yang disuntikkan adalah array, koleksi, atau peta dengan generik, maka Spring akan menanamkan semua kacang yang berjenis dalam array ini (atau struktur data lain). Dalam kasus peta, kuncinya adalah nama bean.


 // ,   DI @Authowired(required = true/false) 

Bagaimana cara membuat DI di bidang pribadi?

Anda dapat menggunakan berbagai jenis implementasi:


  • Konstruktor
  • Setter
  • Injeksi lapangan
  • Nilai

Bagaimana cara menggunakan @Qualifier melengkapi @Autowired?

Spring menyediakan anotasi Kualifikasi untuk mengatasi masalah ambiguitas DI.


 @Bean @Qualifier("SomeClass1") public SomeClass getField() {...} //… @Autowire @Qualifier("SomeField1") public SomeClass someField; 

Jika wadah memiliki beberapa nampan dari jenis yang sama (SomeClass), maka wadah akan menerapkan persis tempat itu, di atas metode @ Bean yang ada kualifikasi yang sesuai. Anda juga tidak bisa menempatkan kualifikasi pada suatu metode, tetapi menggunakan nama bean sebagai parameter kualifikasi.
Nama kacang dapat ditentukan melalui parameter anotasi Bean , dan secara default, ini adalah nama metode pabrik.


Apa objek proxy dan jenis objek proxy apa yang dapat dibuat Spring?

Proxy adalah objek khusus yang memiliki metode publik yang sama dengan kacang, tetapi yang memiliki fungsi tambahan.
Dua jenis proksi:


  • JDK-proxy - proxy dinamis. API dibangun ke dalam JDK. Perlu antarmuka
  • Proxy CGLib - tidak dibangun ke dalam JDK. Digunakan saat antarmuka objek tidak tersedia.

Pro dari objek proxy:


  • Izinkan untuk menambahkan ekstra. logika - manajemen transaksi, keamanan, pencatatan
  • Memisahkan beberapa kode (logging, dll.) Dari logika utama

Bagaimana kacang tunggal diterapkan?

Jika tidak ada instance kacang dalam wadah, metode @ Bean disebut. Jika ada contoh kacang, maka kacang yang sudah dibuat dikembalikan.


Apa itu profil? Apa alasan mereka menggunakannya?

Saat menggunakan konfigurasi Java, Anda dapat menggunakan anotasi @Profile .
Ini memungkinkan Anda untuk menggunakan pengaturan yang berbeda untuk Spring, tergantung pada profil yang ditentukan.
Itu dapat ditempatkan pada kelas-kelas @Configuration dan Component , juga pada metode Bean .


 Profile("!test") //   ,   

 @Bean("dataSource") @Profile("production") public DataSource jndiDataSource() {...} @Bean("dataSource") @Profile("development") public DataSource standaloneDataSource() {...} 

Bagaimana cara menanamkan nilai sederhana dalam properti di Spring?

Anda dapat menggunakan anotasi @Value untuk @Value .
Nilai tersebut dapat diperoleh dari file properti, dari sampah, dll.


 @Value("$some.key") public String stringWithDefaultValue; 

String akan disematkan dalam variabel ini, misalnya, dari properti atau dari tampilan.


Seperti biasa, silakan kirim koreksi atau kesalahan yang ditemukan di PM.

Source: https://habr.com/ru/post/id470305/


All Articles