JavaRush /Java Blog /Random-ID /Kerangka Musim Semi. Perkenalan
Marchello
Level 20
Санкт-Петербург

Kerangka Musim Semi. Perkenalan

Dipublikasikan di grup Random-ID
Halo! Sementara administrasi JavaRush sedang mengerjakan level baru, saya ingin memulai serangkaian artikel pelatihan tentang Spring Framework. Ya, saya tahu bahwa sudah ada banyak materi tentang topik ini di Internet, tetapi, seperti yang ditunjukkan oleh latihan, semuanya berada di tingkat Hello World. Saya ingin berbicara bukan tentang cara menempatkan anotasi dengan benar, tetapi tentang cara kerjanya "di balik terpal". Artikel ini ditujukan bagi mereka yang telah bekerja dengan kerangka ini dalam satu atau lain cara dan akrab dengan konsep dasar. Kerangka Musim Semi.  Pendahuluan - 1

Menginisialisasi konteks.

Jadi mari kita mulai dengan dasar-dasarnya. Menurut pendapat saya, salah satu poin terpenting adalah memahami bagaimana konteks diatur dan kacang diinisialisasi. Seperti yang Anda ketahui, sebelum Spring mulai bekerja, Spring perlu dikonfigurasi. Pada zaman dahulu, hal ini dilakukan dengan menggunakan file xml (pada beberapa proyek, terutama proyek lama, hal ini terus dilakukan hingga hari ini). Berikut adalah contoh kecil dari file konfigurasi tersebut:
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="helloWorld" class="ru.javarush.HelloWorld">
       <property name="message" value="Hello World!"/>
   </bean>

</beans>
Pada umumnya, ini cukup untuk membuat beberapa pengontrol dan meluncurkan startup (yang tidak akan lepas landas). Namun bagaimana konfigurasi ini membuat Spring berfungsi? Dan di sinilah hal-hal menjadi menarik. Agar konfigurasi kita dapat dipahami oleh Spring, ada file XmlBeanDefinitionReader. BeanDefinitionIni adalah komponen Spring internal yang memindai (mem-parsing) xml dan membuat berdasarkan apa yang kami tulis di sana . BeanDefinitionadalah objek yang menyimpan informasi tentang kacang. Hal ini mencakup: dari kelas mana kacang tersebut harus dibuat; cakupan; apakah inisialisasi lambat diinstal; Apakah perlu menginisialisasi sebelum kacang ini properti lain dan lainnya yang dijelaskan dalam xml. Semua yang diterima BeanDefinitionditambahkan ke HashMap, yang pengidentifikasinya adalah nama kacang (ditetapkan oleh Anda atau ditetapkan oleh Spring) dan BeanDefinitionobjek itu sendiri. Setelah semuanya BeanDefinitiondibuat, pahlawan baru muncul di panggung - BeanFactory. Objek ini mengulangi HashMap’es BeanDefinition, membuat kacang berdasarkan pada objek tersebut dan memasukkannya ke dalam wadah IoC. Ada nuansa di sini, sebenarnya ketika aplikasi dimulai, container IoC akan berisi beans yang memiliki cakupan Singleton (diatur secara default), sedangkan sisanya dibuat saat dibutuhkan (prototipe, permintaan, sesi). Dan sekarang penyimpangan kecil, mari berkenalan dengan karakter lain.

Temui BeanPostProcessor. (BPP)

pemroses pos kacangFaktanya adalah kacang belum tentu merupakan kelas logika bisnis untuk aplikasi Anda. Kacang juga disebut kacang infrastruktur. Singkatnya, kacang infrastruktur adalah kelas yang mengonfigurasi kacang logika bisnis Anda (ya, terlalu banyak kacang). Saya akan memberi tahu Anda lebih banyak tentangnya di bawah ini, tetapi untuk membuatnya lebih jelas apa sebenarnya yang dikonfigurasi BPP, saya akan memberikan sebuah contoh. Apakah semua orang familiar dengan ringkasannya @Autowired? Jadi, Anda AutowiredAnnotationBeanPostProcessorbertanggung jawab untuk memastikan bahwa semua kelas Anda tertanam satu sama lain. tidak tahu apa-apa

Mari kita kembali ke BeanFactory

Mengetahui sekarang tentang BPP, Anda perlu mengklarifikasi bahwa ketika melakukan iterasi HashMap, BeanDefinitionsemua terlebih dahulu dibuat dan ditempatkan secara terpisah (bukan dalam wadah IoC) BeanPostProcessor. Setelah ini, kacang reguler logika bisnis kami dibuat, dimasukkan ke dalam wadah IoC, dan konfigurasinya mulai menggunakan BPP yang ditangguhkan secara terpisah. Dan beginilah kejadiannya, setiap BPP mempunyai 2 cara :
postProcessorBeforeInitialization(Object bean, String beanName);
postProcessorAfterInitialization(Object bean, String beanName);
Iterasi melalui bin kami dua kali. Pertama kali metode dipanggil postProcessorBeforeInitialization, dan kedua kali metode dipanggil postProcessorAfterInitialization. Tentunya muncul pertanyaan mengapa diperlukan dua metode, izinkan saya menjelaskannya. Faktanya adalah untuk memproses beberapa anotasi (seperti @Transactional, misalnya), kacang kita digantikan oleh kelas proxy. Untuk memahami mengapa hal ini dilakukan, Anda perlu mengetahui cara kerjanya @Transactional, dan inilah cara kerjanya. Anda perlu menambahkan beberapa baris kode lagi ke metode yang ditandai dengan anotasi ini dengan cepat. Bagaimana cara melakukannya? Benar, dengan membuat kelas proxy, di dalamnya kode yang diperlukan akan ditambahkan ke metode yang diperlukan. Sekarang bayangkan situasi ini, kita mempunyai kelas:
class A {
    @Autowired
    private SomeClass someClass;

    @Transactional
    public void method() {
        // модификатор доступа обязательно public
    }
}
Kelas ini memiliki 2 anotasi @Autowireddan @Transactional. Kedua anotasi tersebut diproses oleh BPP yang berbeda. Jika berhasil terlebih dahulu AutowiredBPP, maka semuanya akan baik-baik saja, tetapi jika tidak, maka kita akan menemui masalah ini. Faktanya adalah ketika kelas proxy dibuat, semua informasi meta hilang. Dengan kata lain, tidak akan ada informasi tentang anotasi @Autowireddi kelas proxy, dan oleh karena AutowiredBPPitu tidak akan berfungsi, yang berarti bidang kita someClassakan memiliki nilai null, yang kemungkinan besar akan menghasilkan NPE. Perlu juga diketahui bahwa di antara pemanggilan metode, -metode dipanggil postProcessorBeforeInitialization, jika ada. Ini pada dasarnya adalah konstruktor kedua, tetapi perbedaannya adalah saat ini semua dependensi kita sudah tertanam di kelas dan kita dapat mengaksesnya dari -metode. Jadi, sekali lagi algoritma inisialisasi konteks: postProcessorAfterInitializationinitinit
  1. XmlBeanDefinitionReadermemindai file konfigurasi xml kami.
  2. Membuat BeanDefinitiondan menempatkannya di dalamnya HashMap.
  3. Datang BeanFactorydan dari ini HashMapsecara terpisah menambahkan semua BeanPostProcessor's.
  4. Membuat BeanDefinitionkacang dari 's dan menempatkannya dalam wadah IoC.
  5. Di sini BPP datang dan mengkonfigurasi kacang ini menggunakan 2 metode.
  6. Siap.
Sebenarnya, itu saja, tulislah apakah Anda menyukai artikel tersebut dan apakah layak untuk terus menulis tutorial semacam itu.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION