Artikel ini memperkenalkan diskusi singkat tentang prinsip injeksi ketergantungan dari kontainer IOC musim semi, dan membagikannya kepada Anda, sebagai berikut:
Tugas utama menginisialisasi wadah IOC adalah membuat peta data beandefinition di wadah IOC. Saya tidak melihat wadah IOC menyuntikkan hubungan ketergantungan kacang.
Dengan asumsi bahwa wadah IOC saat ini telah memuat informasi kacang yang ditentukan pengguna, injeksi ketergantungan terutama terjadi dalam dua tahap.
Dalam keadaan normal, itu dipicu ketika pengguna meminta kacang dari wadah IOC untuk pertama kalinya.
Namun, kami dapat mengontrol atribut init malas dalam informasi beandefinition untuk memungkinkan wadah pra-nonaktifkan kacang, yaitu, proses injeksi ketergantungan kacang tertentu diselesaikan selama proses inisialisasi.
1. Injeksi ketergantungan yang dipicu oleh Getbean
Dalam antarmuka wadah IOC dasar beanfactory, ada definisi antarmuka untuk getbean. Implementasi antarmuka ini adalah tempat injeksi ketergantungan pemicu terjadi. Untuk lebih memahami proses injeksi ketergantungan, kami mulai dengan kelas dasar AbstractBeanFactory dari DefaultListableBeanFactory untuk melihat implementasi Getbean
// Berikut adalah implementasi antarmuka beanfactory, seperti metode antarmuka getbean // metode antarmuka getbean ini pada akhirnya diimplementasikan dengan memanggil dogetbean @override objek publik getbean (nama string) melempar beansException {return doGetBean (name, null, null, false); } @Override public <t> t getbean (nama string, kelas <t> wajib) melempar beansException {return doGetBean (name, wajib, null, false); } @Override Objek publik getBean (nama string, objek ... args) melempar beansException {return doGetBean (name, null, args, false); } public <t> t getbean (nama string, kelas <t> wajib, objek ... args) melempar beansException {return doGetBean (name, wajib, args, false); } // Di sinilah kacang sebenarnya diperoleh, yaitu, di mana injeksi ketergantungan dipicu @suppressWarnings ("Uncecked") dilindungi <T> t doGetBean (nama string akhir, kelas akhir <t> yang diperlukan, objek akhir [] args, Boolean TypeCheckonly) melempar Beansexcepion {nameed -nameed; Kacang objek; // Periksa Singleton Cache dengan penuh semangat untuk singleton yang terdaftar secara manual. // Periksa Singleton Cache dengan penuh semangat untuk singleton yang terdaftar secara manual. // dengan penuh semangat memeriksa cache singleton untuk pendaftaran manual singletons // mengambil kacang dari cache terlebih dahulu dan memproses kacang singleton yang telah dibuat. Jangan berulang kali membuat objek sharedInstance = getsingleton (beanname); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else {logger.debug ("instance pengembalian singleton bean '" + beanname + "'"); }} // GetObjectForBeanInstance di sini melengkapi pemrosesan yang relevan dari pabrik untuk mendapatkan pemrosesan yang relevan dari pabrik untuk mendapatkan hasil produksi pabrik. Perbedaan antara beanfactory dan factorybean telah disebutkan sebelumnya. Proses ini akan dianalisis secara rinci nanti. = getObjectForBeanInstance (sharedInstance, name, beanname, null); } else {// gagal jika kita sudah membuat instance kacang ini: // kita diasumsikan dalam referensi melingkar. if (isPrototypeCurseCreation (beanname)) {lempar beanCurrently increationexception (beanname); } // // Periksa apakah ada beandefinition dalam wadah IOC. Jika tidak ada di pabrik saat ini, ikuti rantai beanfactory induk dan lihat ke atas ParentbeanFactory beanfactory = getParentBeanFactory (); if (parentBeanFactory! = null &&! containsbeandefinition (beanname)) {// tidak ditemukan -> periksa induk. String nametolookup = originalBeanName (name); if (args! = null) {// delegasi untuk orang tua dengan args eksplisit. return (t) parentBeanFactory.getBean (nametolookup, args); } else {// no args -> delegasi ke metode Getbean standar. return ParentBeanFactory.getBean (nametolookup, wajib diminta); }} if (! TypeCheckOnly) {MarkBeanaScreated (beanname); } coba {// dapatkan beandefinition final rootbeandefinition mbd = getmergedlocalbeandefinition (beanname); checkmergedbeandefinition (MBD, beanname, args); // menjamin inisialisasi kacang yang diandalkan kacang saat ini. // memperoleh semua kacang secara rekursif yang tergantung pada kacang saat ini (jika ada) string [] dependson = mbd.getDependson (); if (dependentson! = null) {for (string dep: dependSon) {if (isDependent (beanname, dep)) {lempar beanCreationException baru (mbd.getResourcedescription (), beanname, "Circular tergantung-on antara '" + beanname + "dan' dan '" + " +" + " +" + " +" + "); } registerDependentBean (dep, beanname); getbean (dep); } } //Create Singleton bean instance by calling the createBean method if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) {// Hapus contoh dari Singleton Cache: mungkin telah diletakkan di sana // dengan penuh semangat dengan proses pembuatan, untuk memungkinkan resolusi referensi melingkar. bean = getObjectForBeanInstance (sharedInstance, name, beanname, mbd); } // Ini adalah tempat untuk membuat prototipe biji lain jika (mbd.isprototype ()) {// Ini adalah prototipe -> Buat instance baru. Objek prototipeInstance = null; coba {beforeprototypeCreation (beanname); prototipeInstance = createBean (beanname, mbd, args); } akhirnya {afterprototypeCreation (beanname); } bean = getObjectForBeanInstance (prototipeInstance, name, beanname, mbd); } else {string scopename = mbd.getscope (); scope final scope = this.scopes.get (scopename); if (scope == null) {lempar baru ilegalstateException ("Tidak ada lingkup terdaftar untuk nama lingkup '" + scopename + "'"); } coba {objek scopedInstance = scope.get (beanname, new ObjectFactory <Peject> () {@Override Objek getObject () melempar beansException {beforeprototypecreation (beanname); coba {return createBean (beanName, mbd, argeeance (arger); {return createBean (beanName, mbd, mbd, arger); {return createBean (beanName, mbd, mbd, argeon); oMeryproteon (beanname, mbd, args); {{beanname, mbd, mbd, argeon); }}); bean = getObjectForBeanInstance (ScopedInstance, Name, Beanname, MBD); } catch (ilegalstateException ex) {lempar beanCreationException baru (beanname, "scope '" + scopename + "' tidak aktif untuk utas saat ini; pertimbangkan" + "mendefinisikan proxy yang dilingkupkan untuk kacang ini jika Anda ingin merujuknya dari singleton", ex); }}} catch (beansException ex) {cleanupafterbeanceReationFailure (beanname); lempar ex; }} // Periksa apakah jenis yang diperlukan cocok dengan jenis instance kacang yang sebenarnya. // Ketik Pemeriksaan dilakukan pada kacang yang dibuat di sini. Jika tidak ada masalah, kacang yang baru dibuat dikembalikan. Kacang ini sudah merupakan kacang yang berisi ketergantungan jika (wajib dibutuhkan! = Null && bean! = Null &&! Wajib. } catch (TypeMisMatchException ex) {if (logger.isdebugeNabled ()) {logger.debug ("Gagal mengonversi kacang '" + nama + "' menjadi tipe yang diperlukan '" + classutils.getqualifiedName (wajib) + "", ex); } lempar beannotofrequiredtypeException baru (name, wajib, bean.getClass ()); }} return (t) bean; }Injeksi ketergantungan dipicu di sini. Injeksi ketergantungan terjadi ketika data definisi beand dalam wadah telah ditetapkan. Meskipun kita dapat menggambarkan wadah IOC dengan cara yang paling sederhana, yaitu, perlakukan hashmap, kita hanya bisa mengatakan bahwa hashmap ini adalah struktur data paling dasar dari wadah, bukan seluruh wadah IOC.
Proses injeksi ketergantungan ini akan dijelaskan secara rinci di bawah ini. Gambar 1.1 menunjukkan proses umum injeksi ketergantungan.
Gambar 1.1 Proses Injeksi Ketergantungan
Getbean adalah titik awal injeksi ketergantungan. Setelah itu, CreateBean di AbstractAutowIrecapableBeanFactory akan dipanggil untuk menghasilkan kacang yang diperlukan, dan inisialisasi kacang juga diproses, seperti mengimplementasikan definisi atribut-metode init dalam kode beanden, kacang post-prosesor, dll.
@Override Object Protected CreateBean (String BeanName, RootBeandefinition MBD, Object [] args) melempar BeanCreationException {if (Logger.isdebugeNabled ()) {logger.debug ("Membuat instance bean '" + beanname + ""); } Rootbeandefinition mbdtouse = mbd; // Pastikan Kelas Bean sebenarnya diselesaikan pada titik ini, dan // Kloning definisi kacang dalam kasus kelas yang diselesaikan secara dinamis // yang tidak dapat disimpan dalam definisi kacang gabungan bersama. // Di sini kami menentukan apakah kacang yang akan dibuat dapat dipakai, apakah kelas ini dapat dimuat melalui kelas Loader kelas <?> SecolvedClass = resolveAnclass (MBD, beanname); if (resolvedClass! = null &&! mbd.hasbeanClass () && mbd.getBeanClassName ()! = null) {mbdtouse = rootbeandefinition baru (mbd); mbdtouse.setBeAnclass (SecolvedClass); } // Mempersiapkan penggantian metode. coba {mbdtouse.preparemethodoverrides (); } catch (beandefinitionValidationException ex) {lempar beandefinitionstoreException baru (mbdtouse.getResourcedescription (), beanname, "validasi override metode gagal", ex); } coba {// Berikan beanpostprocessors kesempatan untuk mengembalikan proxy alih -alih instance target bean. // Jika kacang telah mengonfigurasi postprocessor, maka objek proxy yang dikembalikan bean = resolveForeInstantiation (beanname, mbdtouse); if (bean! = null) {return bean; }} Catch (Throwable Ex) {Throw New BeanCreationException (mbdtouse.getResourcedescription (), beanname, "beanpostprocessor sebelum instantiasi kacang gagal", ex); } coba {objek beanInstance = docreateBean (beanname, mbdtouse, args); if (logger.isdebugeNabled ()) {logger.debug ("selesai membuat instance bean '" + beanname + "'"); } return beanInstance; } catch (BeanCreationException ex) {// Pengecualian yang terdeteksi sebelumnya dengan konteks penciptaan kacang yang tepat sudah ... lempar ex; } Catch (secara implisit aplikasiingSingLeTonException ex) {// An ilegalstateException yang akan dikomunikasikan hingga defaultSingLeTonBeanRegistry ... lempar ex; } Catch (Throwable Ex) {Throw New BeanCreationException (mbdtouse.getResourcedescription (), beanname, "pengecualian tak terduga selama penciptaan kacang", ex); }} // Di sebelah Docreate untuk melihat bagaimana kacang dihasilkan objek yang dilindungi DocreateBean (Final String Beanname, Final RootBeandefinition MBD, Objek akhir [] args) {// Instantiate bean. // Digunakan untuk memegang kacang benda yang dibuat Beanwrapper instanceWrapper = null; // Jika itu singleton, pertama -tama hapus kacang dengan nama yang sama di cache if (mbd.issingleton ()) {instanceWrapper = this.factorybeaninstancecache.remove (beanname); } // Ini adalah tempat untuk membuat kacang, dan dilakukan oleh CreateBeanInstance if (instanceWrapper == null) {// Buat instance baru berdasarkan kacang yang ditentukan menggunakan strategi yang sesuai, seperti: Metode pabrik, injeksi otomatis konstruktor, inisialisasi sederhana Instancerapper = createBeanInstance (BeanName, MBD, Arge, MBD, arger); } objek akhir bean = (instanceWrapper! = null? instanceWrapper.getWrappedInstance (): null); Kelas <?> beantype = (instanceWrapper! = Null? InstanceWrapper.getWrappedClass (): null); // Izinkan post-prosesor untuk memodifikasi definisi kacang gabungan. disinkronkan (mbd.postprocessinglock) {if (! mbd.postprocessed) {applyMergedBeandefinitionPostProcessors (MBD, beantype, beanname); mbd.postprocessed = true; }} // Singleton cache yang penuh semangat untuk dapat menyelesaikan referensi melingkar // bahkan ketika dipicu oleh antarmuka siklus hidup seperti BeanfactoryAware. // Apakah perlu untuk mengekspos terlebih dahulu: Singleton & memungkinkan dependensi siklik & kacang saat ini sedang dibuat, mendeteksi dependensi siklik boolean EarlySingletOnexposure = (mbd.issingleton () && this.allowcircularReferences && issingletonCureCreRiceon (BeanName); if (EarlySingLeTonExPosure) {if (logger.isdebugeNabled ()) {logger.debug ("Caching Bean 'dengan penuh semangat'" + beanname + "'untuk memungkinkan penyelesaian referensi sirkular potensial"); } // Untuk menghindari dependensi siklus akhir, objek yang membuat instance dapat ditambahkan ke pabrik sebelum inisialisasi kacang selesai. AddsingleTonFactory (beanname, objek baru <bestigasi> () {@override objek publik getObject () melempar BeansException {// mengandalkan referensi ke kacang lagi, terutama menggunakan smartinstantialiationAware beanprocessor, // AOP yang kita kenal secara langsung. getearlybeanreference (beanname, mbd, bean); } // Inisialisasi instance bean. // Ini adalah inisialisasi kacang, dan injeksi ketergantungan sering terjadi di sini. Penyesalan objek yang terpapar ini kembali sebagai kacang setelah inisialisasi diproses. Object ExposedObject = Bean; coba {// letakkan kacang dan suntikkan setiap nilai atribut. Di antara mereka, mungkin ada atribut yang bergantung pada kacang lainnya, kacang ketergantungan akan diinisialisasi secara rekursif populasi (Beanname, MBD, InstanceWrapper); if (ExposedObject! = null) {// Memanggil metode inisialisasi, seperti init-metod ExposedObject = initializeBean (beanname, eksposedObject, mbd); }} catch (throwable ex) {if (ex instance dari beanCreationException && beanname.equals (((beancreationexception) ex) .getBeanName ())) {throw (beanscreationexception) ex; } else {throw new BeancreationException (mbd.getResourcedescription (), beanname, "inisialisasi kacang gagal", ex); }} if (EarlySingLeTonExPosure) {Object EarlySingLeTonReference = getsingleton (beanname, false); // EarlySingletonReference tidak kosong hanya jika ketergantungan melingkar terdeteksi jika (EarlySingletonReference! = NULL) {if (ExposedObject == bean) {// Jika ExposedObject tidak diubah dalam metode inisialisasi, itu tidak ditingkatkan yang dieksposedObject = EarlySingLeTonReference; } lain if (! this.allowrawinjectionDespitewrapping && hasDependentBean (beanName)) {string [] dependentBeans = getDependentBeans (beanName); Atur <string> AcctualDependentBeans = new LinkedHashset <Rips> (dependentBeans.length); untuk (String DependentBean: DependentBeans) {// Ketergantungan Deteksi if (! RemovesingLeTonifCreatedFeChecheckonly (DependentBean)) {AcctualDependentBeans.add (DependentBean); }} // Karena kacang itu tergantung pada setelah kacang diciptakan harus dibuat, orang yang sebenarnya tidak kosong, yang berarti bahwa kacang itu tergantung pada setelah kacang saat ini dibuat belum dibuat, yaitu, ada name name name (! "'telah disuntikkan ke dalam kacang lainnya [" + stringutils.collectiontocommadelimitedString (aktual dependenbeans) + "] dalam versi mentahnya sebagai bagian dari referensi sirkuler, tetapi akhirnya telah" + "dibungkus. Ini berarti tipe yang sama -sama dengan tipe eager -eager -" + "BEAN" ini seringkali hasilnya dari eager yang lebih dari eager - " +" ini. Bendera 'AlloweAgerInit' dimatikan, misalnya. "); }}}}} // Daftarkan kacang sebagai sekali pakai. Coba {// Daftarkan Bean Berdasarkan SCOPE REGISTERDISPOSABLEBEANIFNECARY (Beanname, Bean, MBD); } catch (beandefinitionValidationException ex) {throw new BeancreationException (mbd.getResourcedescription (), beanname, "tanda tangan penghancuran tidak valid", ex); } return ExposedObject; }Injeksi ketergantungan sebenarnya melibatkan dua proses utama
Dari yang di atas kita dapat melihat bahwa metode yang sangat terkait erat dengan injeksi ketergantungan termasuk
createBeanInstance
Menghasilkan benda java yang terkandung dalam kacang
populeBean.
Memproses proses pemrosesan sifat berbagai objek kacang (mis. Proses pemrosesan ketergantungan)
Mari kita lihat kode sumber CreateBeanInstance terlebih dahulu
/** * Buat instance baru untuk kacang yang ditentukan, menggunakan strategi instance yang sesuai: * Metode pabrik, autowiring konstruktor, atau instance sederhana. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a BeanWrapper for the new instance */ protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // Make sure bean class is actually resolved at this poin. // Konfirmasikan bahwa kelas instance bean yang ingin Anda buat dapat menjadi kelas yang instan <?> Beansclass = resolveAnclass (MBD, beanname); if (beansclass! = null &&! Modifier.ispublic (beansclass.getModifiers ()) &&! mbd.isnonPublicAccessAllowed ()) {throw new BeanscreationException (mbd.getresourcriping (), beanName, "non-bean class (dan non-non non-public: dan non-bean non non-ubername," non non non-publiccription () } Pemasok <?> instancesupplier = mbd.getInstancesupplier (); if (instancesupplier! = null) {return extromFromsupplier (instancesupplier, beanname); } // Jika metode pabrik tidak kosong, gunakan strategi metode pabrik untuk instantiate bean if (mbd.getFactoryMethodName ()! = Null) {return InstantiateUsingFactoryMethod (beanname, mbd, args); } // pintasan saat menciptakan kembali kacang yang sama ... boolean diselesaikan = false; boolean autowirenecary = false; if (args == null) {disinkronkan (mbd.constructorArgumentLock) {// Kelas memiliki beberapa konstruktor, masing -masing konstruktor memiliki parameter yang berbeda, jadi sebelum menelepon, Anda perlu mengunci konstruktor atau metode pabrik yang sesuai sesuai dengan parameter jika (mbd.resolvedConstructorororMethod! autowirenecary = mbd.constructorArgumentSolved; }}} // Jika telah diuraikan, gunakan metode konstruktor parsed tanpa mengunci lagi jika (diselesaikan) {if (autowirenecary) {// konstruktor secara otomatis menyuntikkan kembali autowireconstructor (beanname, mbd, null, null); } else {// konstruktor menggunakan konstruktor default untuk konstruktor instantiatebean (beanname, mbd); }} // Perlu menentukan konstruktor ... // instantiate bean menggunakan konstruktor konstruktor <?> [] Ctors = detectionConstructorsFrombeanPostProcesors (beansclass, beanname); if (cTors! = null || mbd.getResolvedAutoweMode () == rootbeandefinition.autowire_constructor || mbd.hasconstructorargumentValues () ||! objectutils.isempty (args)) {return autowireconstructor (beannectruct (beanname, mbsedor, argsed (args)) {autowructor (beannectry (args)) {autowername (args)) {autowructor (args) {autowructor (args) {autowructor (args) {autowrumor (args) { } // Tidak ada penanganan khusus: Cukup gunakan konstruktor no-arg. // instantiate bean menggunakan konstruktor default; } /*** Instantiate kacang yang diberikan menggunakan konstruktor defaultnya. * @param beanname Nama bean * @param mbd definisi kacang untuk kacang * @return a beanwrapper untuk instance baru */// instantiatebean yang paling umum dilindungi beanwrapper instantiateBean (string final beanname, final rootbeanDefinition mbd) {// instantiate beane -in Instantiation MBD. Strategi instantiasi default adalah // cglibsubclassingInstantiationsstrategy, yaitu, instantiate kacang menggunakan cGlib. coba {objek beaninstance; Parent beanfactory terakhir = ini; if (system.getSecurityManager ()! = null) {beanInstance = accessController.doprivileged (new PrivilegedAction <POMPERTS> () {@Override Public Object run () {return getIntiationstrategy (). Instantiate (MBD, beanName, Parent);}}}}}}}}}}; } else {beanInstance = getInstantiationstrategy (). Instantiate (MBD, Beanname, Parent); } Beanwrapper bw = beanwrapperImpl baru (beaninstance); initbeanwrapper (BW); kembali bw; } Catch (Throwable Ex) {Throw New BeancreationException (MBD.GetResourcedescription (), Beanname, "Instantiation of Bean Failure", ex); }}CGLIB digunakan di sini untuk membuat instantiate kacang. CGLIB adalah perpustakaan kelas untuk generator bytecode, yang menyediakan serangkaian API untuk menyediakan fungsi menghasilkan dan mengonversi bytecode java.
Di Spring AOP, CGLIB juga digunakan untuk meningkatkan Java Bytecode. Dalam wadah IOC, untuk memahami cara menggunakan CGLIB untuk menghasilkan benda kacang, Anda perlu melihat kelas SimpleIntiationstrategy. Ini adalah kelas default yang digunakan oleh Spring untuk menghasilkan benda kacang. Ini menyediakan dua metode untuk membuat instantiasi benda kacang.
Kelas Publik SimpleIntiationstrategy mengimplementasikan Instantiationstrategy {@Override Public Object Instantiate (rootbeandefinition bd, string beanname, pemilik beanfactory) {// Jangan mengganti kelas dengan cGlib jika tidak ada overrides. if (bd.getMethodoverRides (). isEmpty ()) {// Di sini Anda mendapatkan konstruktor atau metode pabrik yang ditentukan untuk membuat instantiate beanConstructor <?> Construcortouse; disinkronkan (bd.constructorArgumentLock) {construcortouse = (constructor <?>) bd.resolvedConstructororFactoryMethod; if (constructoruse == null) {kelas akhir <?> clazz = bd.getBeanClass (); if (clazz.isInterface ()) {lempar beaninstantiationException baru (clazz, "kelas yang ditentukan adalah antarmuka"); } coba {if (System.getSecurityManager ()! = null) {construcortouse = accessController.doprivileged (baru PrivilEdExceptionAction <constructor <? >> () {@Override Public Constructor <?> Run () Throws Exception {return clazz.getDeclaredConstructor <? } else {construcortouse = clazz.getDeclaredConstructor ((class []) null); } bd.resolvedConstructororFactoryMethod = construcortouse; } Catch (Throwable Ex) {Throw New BeanInstantiationException (Clazz, "No Default Constructor Found", Ex); }}} // Instantiate melalui beanutils. Instantiasi beanutil ini membuat kacang melalui konstruktor. Di beanutils, Anda dapat melihat panggilan spesifik ctor.newinstance (args) return beanutils.instantiateclass (construcortouse); } else {// instantiate objek return instantiateWithMethodyection (bd, beanname, pemilik); }}}Penanganan dependensi antara kacang
Entri untuk pemrosesan ketergantungan adalah metode populeBean yang disebutkan di atas. Karena ada terlalu banyak aspek yang terlibat, saya tidak akan memposting kode di sini. Pengantar singkat untuk proses pemrosesan ketergantungan: dalam metode populatebean,
Pertama, dapatkan nilai properti yang ditetapkan dalam beandefinition, dan kemudian mulai proses injeksi ketergantungan.
Pertama, injeksi autowire dapat diproses, byname atau bytype, dan kemudian atribut disuntikkan.
Maka Anda perlu menguraikan referensi kacang. Setelah parsing manajemen, mengelola, manajemen, dll., Anda telah menyiapkan kondisi untuk injeksi ketergantungan. Di sinilah Anda benar -benar mengatur objek kacang ke properti kacang lain yang tergantung pada, dan properti yang diproses beragam.
Injeksi ketergantungan terjadi dalam nilai setPropertyye Beanwrapper, tetapi penyelesaian spesifik diimplementasikan dalam beanwrapper subclass beanwrapperImpl. Ini akan menyelesaikan injeksi nilai properti kacang, termasuk injeksi array, injeksi kelas koleksi seperti daftar, dan injeksi kelas non-pengumpulan.
Setelah serangkaian suntikan, proses injeksi ketergantungan dari berbagai sifat kacang selesai.
Selama proses pembuatan kacang dan injeksi ketergantungan objek, injeksi ketergantungan perlu diselesaikan secara rekursif berdasarkan informasi dalam lefinisi beand.
Dari proses rekursi sebelumnya, kita dapat melihat bahwa rekursi ini semuanya portabel dengan Getbean.
Rekursi adalah untuk menemukan kacang yang diperlukan dan membuat panggilan rekursif ke kacang dalam sistem konteks;
Rekursi lain adalah memanggil metode Container Getbean secara rekursif selama injeksi ketergantungan untuk mendapatkan kacang ketergantungan kacang saat ini, dan juga memicu penciptaan dan injeksi kacang ketergantungan.
Saat melakukan injeksi ketergantungan pada sifat -sifat kacang, proses penguraian juga merupakan proses rekursif. Dengan cara ini, menurut ketergantungan, penciptaan dan injeksi kacang diselesaikan lapisan demi lapis sampai penciptaan kacang saat ini akhirnya selesai. Dengan penciptaan kacang tingkat atas ini dan penyelesaian injeksi ketergantungan atributnya, itu berarti bahwa solusi injeksi dari seluruh rantai ketergantungan yang terkait dengan kacang saat ini selesai.
Setelah penciptaan kacang dan injeksi ketergantungan selesai, serangkaian kacang yang dihubungkan oleh dependensi ditetapkan dalam wadah IOC. Kacang ini bukan lagi objek Java sederhana. Setelah hubungan ketergantungan antara seri kacang dan kacang dibuat, dapat digunakan dengan sangat mudah untuk aplikasi tingkat atas melalui metode antarmuka IOC yang relevan.
2. Atribut malas-malas dan pra-instance
Dalam metode refresh sebelumnya, kita dapat melihat bahwa finishbeanfactoryInitialisasi dipanggil untuk memproses kacang yang dikonfigurasi dengan malas-init.
Faktanya, dalam metode ini, pemrosesan atribut malas-init dienkapsulasi, dan pemrosesan aktual dilakukan dalam metode preinstantiateSingleton dari wadah dasar dari DefaultListableAnfactory. Metode ini melengkapi kacang singleton pra-tidak tertanam, dan penyelesaian pra-stasiun ini secara cerdik didelegasikan ke wadah untuk diimplementasikan. Jika diperlukan pra-penetapan, maka GetBean digunakan di sini untuk memicu injeksi ketergantungan. Dibandingkan dengan pemicu injeksi ketergantungan normal, waktu dan kesempatan pemicu hanya berbeda. Di sini, injeksi ketergantungan terjadi selama proses penyegaran wadah, yaitu selama proses inisialisasi wadah IOC, tidak seperti injeksi ketergantungan biasa, ketika wadah meminta kacang untuk pertama kalinya setelah wadah IOC diinisialisasi melalui Getbean.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.