Singkatnya, tidak. Anda tidak dapat autowire atau secara manual kawat bidang statis di Spring. Anda harus menulis sendiri logika Anda untuk melakukan ini.
Ketika Anda menemukan kode lama melakukan ini, ini merupakan anti-pola. Juling, miringkan kepala, dan temukan cara yang lebih baik untuk menyelesaikan masalah. Anda akan senang melakukannya.
ada ide bagaimana saya bisa menggunakan pendekatan ini ketika menginisialisasi repositori?
kiedysktos
3
Downside: Tidak ada jaminan yang someThingtelah diinisialisasi jika diakses secara statis: NewClass.staticMethodWhichUsesSomething();mungkin melempar NPE jika digunakan sebelum inisialisasi aplikasi
Neeraj
Bisakah Anda menghindari peringatan Instance methods should not write to "static" fields (squid:S2696)?
user7294900
@ user7294900: nonaktifkan peringatan ini hanya untuk kasus ini, sangat spesifik.
izogfif
@izogfif masih menjadi masalah jika saya memilih solusi ini dalam kasus dan kelas yang luas
user7294900
67
@Autowired dapat digunakan dengan setter sehingga Anda bisa memiliki setter memodifikasi bidang statis.
Mengapa Anda menyarankan untuk tidak melakukan ini?
Jon Lorusso
3
Hmmm .. perasaan saya tentang mengapa itu tidak direkomendasikan adalah, karena dengan demikian contoh statis di kelas berada di luar kendali pegas. Setelah disuntikkan bidang statis yang acuan bagi semua contoh objek dari kelas yang sesuai (sekitarnya). Tapi, perilaku ini mungkin persis seperti yang diharapkan terjadi, sehingga dapat dilihat sebagai bug atau fitur ...
matthaeus
1
Ya @matthaeus, ini persis fitur yang saya harapkan ketika perlu mengakses org.springframework.core.env.Environment:@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
user1767316
@ JonLorusso dan semua Karena ketika pemuat kelas memuat nilai statis, konteks Spring belum perlu dimuat. Jadi pemuat kelas tidak akan dengan benar menyuntikkan kelas statis di dalam kacang dan akan gagal. Jawaban diberikan oleh Andrea T
Jeril Kuruvila
14
Masuk komponen autowired Anda dalam metode @PostConstruct
Anda harus berusaha menggunakan injeksi pegas di mana mungkin karena ini adalah pendekatan yang direkomendasikan tetapi ini tidak selalu mungkin karena saya yakin Anda bisa membayangkan karena tidak semuanya bisa ditarik dari wadah pegas atau Anda mungkin berurusan dengan sistem warisan.
Catatan pengujian juga bisa lebih sulit dengan pendekatan ini.
Penafian Ini tidak berarti standar dan mungkin ada cara musim semi yang lebih baik untuk melakukan ini. Tak satu pun dari jawaban di atas mengatasi masalah perkabelan bidang statis publik.
Saya ingin menyelesaikan tiga hal.
Gunakan pegas untuk "Autowire" (Saya menggunakan @Nilai)
Kami telah memeriksa 1 & 2 sekarang bagaimana cara mencegah panggilan ke setter, karena kami tidak dapat menyembunyikannya.
@Component@AspectpublicclassFinalAutowiredHelper{@Before("finalMethods()")publicvoid beforeFinal(JoinPoint joinPoint){thrownewFinalAutowiredHelper().newModifySudoFinalError("");}@Pointcut("execution(* com.free.content.client..*.finalSetBranch(..))")publicvoid finalMethods(){}publicclassModifySudoFinalErrorextendsError{privateString msg;publicModifySudoFinalError(String msg){this.msg = msg;}@OverridepublicString getMessage(){return"Attempted modification of a final property: "+ msg;}}
Aspek ini akan membungkus semua metode mulai dengan final dan melemparkan kesalahan jika mereka dipanggil.
Saya tidak berpikir ini sangat berguna, tetapi jika Anda oCD dan ingin menjaga Anda kacang polong dan wortel dipisahkan ini adalah salah satu cara untuk melakukannya dengan aman.
Pegas Penting tidak memanggil aspek Anda saat memanggil fungsi. Membuat ini lebih mudah, buruk saya mengerjakan logika sebelum mencari tahu itu.
Meskipun kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan tentang bagaimana dan mengapa ini menyelesaikan masalah akan sangat membantu untuk meningkatkan kualitas posting Anda, dan mungkin menghasilkan lebih banyak suara. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang. Harap edit jawaban Anda untuk menambahkan penjelasan dan berikan indikasi tentang batasan dan asumsi apa yang berlaku.
bunyi bip ganda
Saya pikir jawaban ini mungkin tidak memerlukan penjelasan sama sekali.
Jawaban:
Singkatnya, tidak. Anda tidak dapat autowire atau secara manual kawat bidang statis di Spring. Anda harus menulis sendiri logika Anda untuk melakukan ini.
sumber
@AutoWired
sumber
someThing
telah diinisialisasi jika diakses secara statis:NewClass.staticMethodWhichUsesSomething();
mungkin melempar NPE jika digunakan sebelum inisialisasi aplikasiInstance methods should not write to "static" fields (squid:S2696)
?@Autowired
dapat digunakan dengan setter sehingga Anda bisa memiliki setter memodifikasi bidang statis.Hanya satu saran terakhir ... JANGAN
sumber
@Component public class SpringAppEnv{ public static Environment _env; @Autowired public void setEnv(Environment env) {_env = env;} }
Masuk komponen autowired Anda dalam metode @PostConstruct
sumber
Instance methods should not write to "static" fields (squid:S2696)
?Buat kacang yang Anda dapat autowire yang akan menginisialisasi variabel statis sebagai efek samping.
sumber
Anda dapat mencapai ini menggunakan notasi XML dan
MethodInvokingFactoryBean
. Sebagai contoh, lihat di sini .Anda harus berusaha menggunakan injeksi pegas di mana mungkin karena ini adalah pendekatan yang direkomendasikan tetapi ini tidak selalu mungkin karena saya yakin Anda bisa membayangkan karena tidak semuanya bisa ditarik dari wadah pegas atau Anda mungkin berurusan dengan sistem warisan.
Catatan pengujian juga bisa lebih sulit dengan pendekatan ini.
sumber
Ingin menambahkan jawaban bahwa bidang statis perkabelan otomatis (atau konstan) akan diabaikan, tetapi juga tidak akan membuat kesalahan:
sumber
Anda dapat menggunakan ApplicationContextAware
kemudian
sumber
Penafian Ini tidak berarti standar dan mungkin ada cara musim semi yang lebih baik untuk melakukan ini. Tak satu pun dari jawaban di atas mengatasi masalah perkabelan bidang statis publik.
Saya ingin menyelesaikan tiga hal.
Objek saya terlihat seperti ini
Kami telah memeriksa 1 & 2 sekarang bagaimana cara mencegah panggilan ke setter, karena kami tidak dapat menyembunyikannya.
Aspek ini akan membungkus semua metode mulai dengan final dan melemparkan kesalahan jika mereka dipanggil.
Saya tidak berpikir ini sangat berguna, tetapi jika Anda oCD dan ingin menjaga Anda kacang polong dan wortel dipisahkan ini adalah salah satu cara untuk melakukannya dengan aman.
Pegas Penting tidak memanggil aspek Anda saat memanggil fungsi. Membuat ini lebih mudah, buruk saya mengerjakan logika sebelum mencari tahu itu.
sumber
sumber