Dalam aplikasi MVC musim semi, saya menginisialisasi variabel di salah satu kelas layanan menggunakan pendekatan berikut:
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/userLibrary.xml");
service = context.getBean(UserLibrary.class);
UserLibrary adalah utilitas pihak ketiga yang saya gunakan dalam aplikasi saya. Kode di atas menghasilkan peringatan untuk variabel 'konteks'. Peringatannya ditunjukkan di bawah ini:
Resource leak: 'context' is never closed
Saya tidak mengerti peringatannya. Karena aplikasinya adalah aplikasi Spring MVC, saya tidak dapat benar-benar menutup / menghancurkan konteks saat saya merujuk ke layanan saat aplikasi sedang berjalan. Apa sebenarnya peringatan yang coba diberitahukan kepada saya?
java
eclipse
spring
spring-mvc
ziggy
sumber
sumber
Jawaban:
Karena konteks aplikasi adalah
ResourceLoader
(yaitu operasi I / O), aplikasi menghabiskan sumber daya yang perlu dibebaskan di beberapa titik. Ini juga merupakan perpanjangan dariAbstractApplicationContext
implementasiClosable
. Jadi, ini punyaclose()
metode dan dapat digunakan dalam pernyataan coba-dengan-sumber daya .Apakah Anda benar-benar perlu membuat konteks ini adalah pertanyaan yang berbeda (Anda menautkannya), saya tidak akan berkomentar tentang itu.
Memang benar bahwa konteksnya ditutup secara implisit saat aplikasi dihentikan tetapi itu tidak cukup baik. Eclipse benar, Anda perlu mengambil tindakan untuk menutupnya secara manual untuk kasus lain guna menghindari kebocoran classloader.
sumber
ApplicationContext
inteface dasar tidak menyediakanclose()
metode,ConfigurableApplicationContext
(yangClassPathXmlApplicationContext
mengimplementasikan) tidak dan meluasCloseable
ke boot, jadi Anda dapat menggunakan paradigma coba-dengan-sumber daya Java 7.ApplicationContext
dan menggaruk-garuk kepala saya mengapa saya mendapatkan peringatan ketika tampaknya tidak ada metode dekat yang tersedia ...close()
tidak ditentukan dalamApplicationContext
antarmuka.Satu-satunya cara untuk menghilangkan peringatan dengan aman adalah sebagai berikut
Atau, di Java 7
Perbedaan mendasarnya adalah karena Anda memberi contoh konteks secara eksplisit (yaitu dengan menggunakan
new
) Anda tahu kelas yang Anda buat, sehingga Anda dapat mendefinisikan variabel Anda sesuai.Jika Anda tidak membuat instance AppContext (yaitu menggunakan yang disediakan oleh Spring) maka Anda tidak dapat menutupnya.
sumber
new ClassPathXmlApplicationContext(...);
Harus di luar blok percobaan. Maka tidak perlu pemeriksaan nol. Jika konstruktor melontarkan eksepsi makactx
bernilai null danfinally
blok tidak dipanggil (karena eksepsi dilemparkan ke luar blok percobaan). Jika konstruktor tidak mengeluarkan pengecualian makatry
blok dimasukkan danctx
tidak boleh null, jadi tidak perlu untuk pemeriksaan null.Pemeran sederhana menyelesaikan masalah:
sumber
Karena konteks Aplikasi memiliki instance ClassPathXmlApplicationContext dan metode close () yang sama. Saya hanya akan MENGECAST objek appContext dan memanggil metode close () seperti di bawah ini.
Ini akan memperbaiki peringatan Kebocoran Sumber Daya.
sumber
coba ini. Anda perlu menerapkan cast untuk menutup applicationcontext.
sumber
Bahkan saya mendapat peringatan yang sama persis, yang saya lakukan hanyalah menyatakan di
ApplicationContext
luar fungsi utama sebagaiprivate static
dan ta-da, masalah diperbaiki.sumber
@SupressWarnings
anotasi, tetapi masih lebih baik untuk menyelesaikan akar masalah, bukan begitu?Transmisi adalah resolusi yang tepat untuk masalah ini. Saya menghadapi masalah yang sama menggunakan baris di bawah ini.
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
Untuk mengatasi peringatan tersebut turunkan saja
ctx
objek seperti di bawah ini dan kemudian tutup.((AnnotationConfigApplicationContext) ctx).close();
sumber
Downcast konteksnya ke ConfigurableApplicationContext.
sumber
((ConfigurableApplicationContext)(context)).close();
mungkin ini adalah jawaban yang benarDalam kasus saya, kebocoran menghilang
sumber
Ini berhasil paling baik untuk saya.
sumber
Jika Anda menggunakan ClassPathXmlApplicationContext maka Anda dapat menggunakan
untuk menutup masalah kebocoran sumber daya.
Jika Anda menggunakan AbstractApplicationContext maka Anda dapat mentransmisikannya dengan metode tutup.
Itu tergantung pada jenis konteks yang digunakan dalam aplikasi.
sumber
sumber
Anda membuat konteks menjadi variabel statis, yang berarti bahwa konteks tersedia untuk semua metode statis di kelas, dan tidak lagi terbatas pada ruang lingkup metode utama. Jadi alat tidak dapat berasumsi bahwa itu harus ditutup di akhir metode lagi, jadi tidak mengeluarkan peringatan lagi.
sumber
Ya, antarmuka
ApplicationContext
tidak memilikiclose()
metode, jadi saya suka menggunakan kelasAbstractApplicationContext
untuk menggunakanclose
metode itu secara eksplisit dan juga di sini Anda dapat menggunakan kelas konfigurasi Aplikasi Musim Semi menggunakan anotasi, bukanXML
tipe.Resource leak: 'context' is never closed
peringatan Anda hilang sekarang.sumber
memiliki solusi sederhana, cukup masukkan tabung Inti ke dalam perpustakaan, yang diberikan di tautan ini [unduh file tabung inti untuk musim semi] [1] [1]: https://static.javatpoint.com/src/sp/spcorejars. zip
sumber
Metode dekat telah ditambahkan ke antarmuka ConfigurableApplicationContext, jadi hal terbaik yang dapat Anda lakukan untuk mendapatkan aksesnya adalah:
sumber