Dalam artikel ini saya ingin berkongsi masalah yang saya hadapi baru-baru ini, yang saya rasa mungkin menarik minat anda.
Apakah isunya?
Kod sumber untuk kedua-dua persekitaran ujian dan pengeluaran adalah sama, dan kedua-dua persekitaran tempatan dan ujian berjalan dengan baik, hanya persekitaran pengeluaran dijalankan dengan NPE kelas perkhidmatan yang gagal dimuatkan, yang ditambah untuk keperluan baharu. Kelas ini mewarisi antara muka daripada pakej Peribadikan (kit alatan yang dibangunkan sendiri).
Struktur Projek
Reka bentuk Customize bergantung pada Spring untuk mengurus API dan perkhidmatan. Dengan pengimbasan automatik Spring, kelas biasa ApiEnhancer dan ServiceEnhancer dimuatkan apabila memulakan kelas dan mendapatkan contoh oleh ApplicationContext. Penyahpepijatan mendapati bahawa apabila memuatkannya, ApplicationContext adalah batal dan belum dimulakan lagi. Ia dimulakan dalam kaedah setApplicationContext dengan melaksanakan ApplicationContextAware, jadi adalah spekulasi bahawa kaedah setApplicationContext belum dilaksanakan.
Semasa proses pemuatan kelas ApplicationContextProvider, kaedah statik dimuatkan ke dalam Kawasan Kaedah semasa fasa permulaan. Walau bagaimanapun, apabila menggunakan ApplicationContext untuk mendapatkan contoh kacang, kaedah statik digunakan secara langsung oleh nama kelas. Selagi API dicipta sebelum ApplicationContextProvider diperuntukkan memori dalam timbunan dan dijadikan instantiated, kaedah setApplicationContext tidak akan digunakan untuk memulakan.
AppContextProvider menggunakan anotasi @Component, dan Api menggunakan anotasi @RestController, dan kedua-dua kelas berada dalam laluan yang sama. Walau bagaimanapun, apabila Spring mengimbas dan memuatkannya, tiada susunan khusus, yang bermaksud setiap satu daripada kedua-dua kelas boleh dibuat sebelum yang lain. Dalam persekitaran pengeluaran, Api dicipta sebelum applicationContextProvider, menyebabkan apabila kaedah statik digunakan secara langsung oleh nama kelas untuk mendapatkan kacang, applicationContext telah TIDAK telah dimulakan.
Penyelesaian
Jika kaedah setApplicationContext kelas pelaksanaan antara muka ApplicationContextAware belum dilaksanakan, semak dahulu sama ada kelas pelaksanaan telah ditetapkan kepada pemuatan malas atau sama ada projek telah mengkonfigurasi pemuatan malas global.
Dalam projek ini, masalah itu disebabkan oleh susunan penciptaan kelas pelaksanaan antara muka ApiEnhancer dan ApplicationContextAware, dan kelas Api hanyalah API RESTful biasa yang mengendalikan logik perniagaan dan boleh dimuatkan apabila dipanggil oleh bahagian hadapan- halaman akhir. Oleh itu, menukar kepada pemuatan malas menyelesaikan masalah.
Adalah dinasihatkan untuk meminimumkan hubungan pergantungan antara kelas dari segi susunan pemuatan. Jika tidak dapat dielakkan, pemuatan malas atau anotasi seperti @DependsOn, @Order, @Priority boleh digunakan untuk mengawal susunan pemuatan kacang.
Mengapakah susunan penciptaan persekitaran pengeluaran dan persekitaran ujian berbeza?
Mari kita nyahpepijat untuk menyemak proses pengimbasan Spring.
Bermula dengan kaedah imbasan ClassPathBeanDeterminationScanner.
kaedah doScan
kaedah scanCandidateComponents ClassPathScanningCandidateComponentProvider
kaedah findAllClassPathResources bagi PathMatchingResourcePatternResolver
kaedah doFindPathMatchingJarResources
JarFile ialah kelas dalam Pustaka Standard Java di bawah pakej java.util.jar, yang mewarisi dan memanjangkan ZipFile. jarFile.entries() mengembalikan iterator bernama JarEntryIterator.
JarExitIterator ialah pelaksanaan Corak Iterator, yang berulang pada entri kelas induk JarFile.
Kaedah entri ZipFile mengembalikan iterator bernama ZipExitIterator.
Kaedah nextElement ZipExitIterator menggunakan kaedah seterusnya, yang seterusnya menggunakan kaedah getNextEntry.
getNextEntry ialah kaedah asli.
Kaedah asli dilaksanakan dalam bahasa bukan Java dan digunakan dalam Mesin Maya Java untuk melaksanakan fungsi asas, yang mungkin berbeza-beza bergantung pada persekitaran (Sistem Pengendalian atau versi JDK). Pakej JAR sendiri tidak mempunyai pesanan, jadi pesanan traversal sebenar mungkin berbeza-beza bergantung pada alatan dan persekitaran pembungkusan JAR yang berbeza.
Atas ialah kandungan terperinci Isu pelaksanaan kaedah setApplicationContext bagi antara muka applicationContextAware dan gagal mendapatkan Spring beans. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!