Jika injeksi konstruktor digunakan, skenario ketergantungan melingkar yang tidak dapat diuraikan dapat dibuat.
Apa itu ketergantungan melingkar
Ketergantungan melingkar sebenarnya adalah referensi melingkar, yaitu, dua atau lebih kacang saling menampung dan akhirnya membentuk loop tertutup. Misalnya, A tergantung pada B, B tergantung pada C, dan C tergantung pada A. seperti yang ditunjukkan pada gambar di bawah ini:
Perhatikan bahwa ini bukan panggilan loop ke fungsi, tetapi saling ketergantungan dari objek. Panggilan loop sebenarnya adalah loop dead kecuali ada kondisi akhir.
Ada skenario ketergantungan loop di musim semi:
(1) Ketergantungan melingkar dari konstruktor (2) ketergantungan melingkar dari atribut bidang.
Bagaimana mendeteksi apakah ada ketergantungan melingkar
Relatif mudah untuk mendeteksi ketergantungan melingkar. Saat kacang dibuat, ia dapat menandai kacang. Jika panggilan rekursif kembali dan menemukan bahwa itu sedang dibuat, itu berarti ketergantungan melingkar.
Inilah situasi yang saya temui, struktur kode adalah sebagai berikut:
Kelas Konfigurasi SPRINGSECURUTY:
@ConfigurationPublic kelas browserSecurityConfig memperluas WebSecurityConfigurerAdapter {private final userDetailSService userDetailSservice; / ** * menyuntikkan UserDetailSService melalui Konstruktor Kelas Konfigurasi */ @Autowired BrowserSecurityConfig Publik (userDetailsService userDetailsService) {this.userdetailsService = userDetailSservice; } / ** * mendeklarasikan enkripsi enkoder di kelas konfigurasi * / @bean public passwordEncoder kata sandi () {return bcryptpassworderCoder baru (); } ... ...}Kelas UserDetailSService:
@ComponentPublic kelas myUserDetailService mengimplementasikan userDetailsService {private final passwordEncoder kata sandi; Logger Private Logger = LoggerFactory.GetLogger (getClass ()); / ** * menyuntikkan kata sandi melalui konstruktor */ @Autowired public myuserdetailService (kata sandi kata sandi kata sandi) {this.passwordEncoder = kata sandiinen; } ... ...}Setelah berjalan, Spring melempar pesan kesalahan berikut:
Keterangan:
Ketergantungan dari beberapa kacang dalam konteks aplikasi membentuk siklus:
┌────┐
| BrowserSecurityConfig didefinisikan dalam file [d: /code/java/ideaprojects/mango-security/mango-security browser/target/classses/stu/mango/security/browser/browsersecurityconfig.class.class]
↑ ↓
| MyUserdetailService didefinisikan dalam file [d: /code/java/ideaprojects/mango-security/mango-security wrowser/target/classes/stu/mango/security/browser/myuserdetailservice.class]]
└────┘
Dalam contoh ini, BrowserSecurityConfig menyuntikkan instance UserDetailsService melalui konstruktor, dan UserDetailsService disuntikkan ke dalam kata sandi yang dinyatakan dalam browserSecurityConfig melalui konstruktor.
Singkatnya, ketergantungan melingkar kacang pegas berarti bahwa Kelas A perlu menyuntikkan contoh kelas B (atau kacang yang dinyatakan dalam B) ke dalam konstruktor, sementara Kelas B perlu menyuntikkan contoh Kelas A (atau kacang yang dinyatakan dalam a) ke dalam konstruktor. Jika kacang Kelas A dan Kelas B dikonfigurasi untuk menyuntikkan satu sama lain, wadah Spring IOC mendeteksi referensi loop ini saat runtime dan meningkatkan beanCurrently increationexception. Berbeda dengan kasus khas (tanpa ketergantungan melingkar), ketergantungan melingkar antara kacang A dan kacang B memaksa salah satu kacang disuntikkan ke yang lain sebelum diinisialisasi sepenuhnya (ini adalah skenario khas ayam "pertama atau telur pertama").
Larutan
Sederhananya, itu bukan untuk menggunakan injeksi ketergantungan berbasis konstruktor. Itu dapat diselesaikan dengan metode berikut.
Gunakan anotasi @Autowired di lapangan dan biarkan Spring memutuskan untuk menyuntikkan pada waktu yang tepat. 【menyarankan】
Ganti injeksi ketergantungan berbasis konstruktor dengan injeksi ketergantungan berbasis setter untuk menyelesaikan ketergantungan melingkar.
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.