. .
Tetapi jika anda bertanya lebih dalam, lebih dalam sedikit, anda boleh menyejukkan sebilangan besar orang.
Contohnya: Mengapakah pemuat kelas tomcat melanggar model perwakilan ibu bapa?
Untuk mengelakkan anda daripada menghadapi situasi seperti ini semasa temuduga, artikel ini akan mengaturkan perkara ini.
Kami akan membincangkannya dalam 4 bahagian:
Apakah mekanisme pemuatan kelas?
Menukar hasil kompilasi kod daripada kod mesin tempatan kepada kod bait ialah satu langkah kecil dalam format storan, tetapi satu langkah besar dalam pembangunan bahasa pengaturcaraan.
Pasukan reka bentuk mesin maya melaksanakan tindakan "mendapatkan aliran bait binari yang menerangkan kelas ini melalui nama kelas yang layak sepenuhnya" dalam fasa pemuatan kelas di luar mesin maya Java, supaya aplikasi boleh memutuskan cara melakukannya Dapatkan kelas yang diperlukan. Modul kod yang melaksanakan tindakan ini dipanggil "pemuat kelas".
Walaupun pemuat kelas hanya digunakan untuk melaksanakan tindakan pemuatan kelas, peranannya dalam program Java jauh daripada terhad kepada peringkat pemuatan kelas. Untuk mana-mana kelas, pemuat kelas yang memuatkannya dan kelas itu sendiri perlu mewujudkan keunikannya dalam mesin maya Java Setiap pemuat kelas mempunyai ruang nama kelas bebas.
Ayat ini boleh dinyatakan dengan cara yang lebih popular: membandingkan sama ada dua kelas adalah "sama" hanya masuk akal jika kedua-dua kelas dimuatkan oleh pemuat kelas yang sama dimuatkan oleh mesin maya yang sama selagi pemuat kelas yang memuatkannya berbeza, kedua-dua kelas itu mestilah tidak sama.
1 Dari perspektif mesin maya Java, hanya terdapat dua pemuat kelas yang berbeza: satu ialah Bootstrap ClassLoader, yang menggunakan bahasa C++ Pelaksanaan (HotSpot sahaja) adalah sebahagian. daripada mesin maya itu sendiri; yang lain ialah semua pemuat kelas lain, yang dilaksanakan dalam bahasa Java, bebas daripada mesin maya, dan semuanya mewarisi daripada kelas abstrakjava.lang.ClassLoader
.
2 Dari perspektif pembangun Java, pemuatan kelas boleh dibahagikan kepada butiran lanjut Kebanyakan pengaturcara Java akan menggunakan tiga pemuat kelas berikut yang disediakan oleh sistem:
sun.misc.Launcher$ExtClassLoader
, yang bertanggungjawab untuk mencampurkan semua perpustakaan kelas dalam direktori JAVA_HOME/lib/ext atau dalam laluan yang ditentukan oleh pembolehubah sistem java.ext.dirs . Pembangun boleh menggunakan pemuat kelas sambungan secara langsung. sun.misc.Launcher$ExtClassLoader
实现,它负责夹杂JAVA_HOME/lib/ext 目录下的,或者被java.ext.dirs 系统变量所指定的路径中的所有类库。开发者可以直接使用扩展类加载器。sun.misc.Launcher$AppClassLoader
Application ClassLoader:
Pemuat kelas ini terdiri daripadasun.misc.Launcher$AppClassLoader
pelaksanaan. Memandangkan pemuat kelas ini ialah nilai pulangan kaedah getSystemClassLoader dalam ClassLoader, ia juga menjadi pemuat kelas sistem. Ia bertanggungjawab untuk memuatkan perpustakaan kelas yang ditentukan pada laluan kelas pengguna (ClassPath). Pembangun boleh menggunakan pemuat kelas ini secara langsung Jika aplikasi tidak mentakrifkan pemuat kelasnya sendiri, ini biasanya pemuat kelas lalai dalam program. gambar
). Model delegasi induk memerlukan bahawa sebagai tambahan kepada pemuat kelas permulaan peringkat atas, semua pemuat kelas lain harus dimuatkan oleh pemuat kelas induk mereka sendiri Hubungan induk-anak antara pemuat kelas di sini secara amnya tidak direalisasikan melalui warisan, tetapi melalui pewarisan. . Mereka semua menggunakan perhubungan komposisi untuk menggunakan semula kod pemuat induk. 🎜Nota: Semasa temu duga, penemuduga juga boleh bertanya direktori mana yang dimuatkan oleh pemuat kelas yang sepadan. 🎜🎜🎜Model delegasi induk pemuat kelas telah diperkenalkan semasa JDK1.2 dan digunakan secara meluas dalam semua program Java berikutnya Walau bagaimanapun, ia bukan model kekangan mandatori, tetapi disyorkan oleh pereka bentuk Java kepada pelaksanaan pemuat kelas. 🎜Hubungan antara setiap pemuat kelas dalam rajah dipanggil
Model perwakilan ibu bapa pemuat kelas
Proses kerja model perwakilan induk ialah: jika pemuat kelas menerima permintaan pemuatan kelas, ia tidak akan cuba memuatkan kelas itu sendiri terlebih dahulu, tetapi mewakilkan permintaan itu kepada pemuat kelas induk untuk diselesaikan. Ini benar untuk setiap peringkat pemuat kelas, jadi semua permintaan pemuatan akhirnya harus dihantar ke pemuat kelas permulaan peringkat atas Hanya apabila pemuat induk memberi maklum balas bahawa ia tidak dapat menyelesaikan permintaan (permintaan yang diperlukan tidak ditemui dalam skop cariannya ) kelas), subloader akan cuba memuatkannya dengan sendirinya.
Jika model delegasi induk tidak digunakan dan setiap pemuat kelas memuatkannya dengan sendirinya, jika pengguna menulis kelas yang dipanggil java.lang.Object dan meletakkannya dalam ClassPath program, sistem akan mempunyai beberapa perbezaan kelas , tingkah laku paling asas dalam sistem jenis Java tidak boleh dijamin. Permohonan juga akan menjadi kucar-kacir.
java.lang.ClassLoader
3. Bagaimana untuk memecahkan model delegasi ibu bapa?
Kali kedua: Ia disebabkan oleh kecacatan model ini sendiri.Kami mengatakan bahawa model delegasi induk menyelesaikan masalah menyatukan kelas asas setiap pemuat kelas (semakin banyak kelas asas dimuatkan oleh pemuat peringkat atas Sebab mengapa kelas asas dipanggil "asas" adalah kerana mereka Ia sentiasa API yang dipanggil oleh kod pengguna, tetapi tiada jaminan Bagaimana jika kelas asas memanggil kod pengguna?
Ini tidak mustahil. Contoh biasa ialah perkhidmatan JNDI kini merupakan perkhidmatan standard dalam Java Kodnya dimuatkan oleh pemuat kelas permulaan (rt.jar yang diletakkan dalam JDK1.3), tetapi ia perlu dipanggil dan dilaksanakan oleh bebas. vendor. Dan gunakan kod penyedia antara muka JNDI (SPI, Antara Muka Pembekal Perkhidmatan) di bawah ClassPath aplikasi, tetapi adalah mustahil untuk pemuat kelas permulaan untuk "mengecam" kod ini. Kerana kelas ini tiada dalam rt.jar
, Tetapi pemuat kelas permulaan perlu dimuatkan semula. Apa yang perlu dilakukan? rt.jar
中,但是启动类加载器又需要加载。怎么办呢?
为了解决这个问题,Java设计团队只好引入了一个不太优雅的设计:线程上下文类加载器(Thread Context ClassLoader)。这个类加载器可以通过java.lang.Thread
Kali ketiga: Untuk mencapai palam panas, penggunaan panas dan modularisasi, yang bermaksud menambah fungsi atau menolak fungsi tanpa dimulakan semula, anda hanya perlu menggantikan modul bersama-sama dengan pemuat kelas untuk mencapai penggantian kod panas.
Buku itu juga berkata: Pada asasnya terdapat konsensus dalam program Java: Penggunaan OSGI pemuat kelas adalah berbaloi untuk dipelajari Memahami pelaksanaan OSGI boleh dianggap sebagai menguasai intipati pemuat kelas. Hebat! ! ! Kini, kami pada asasnya telah memahami prinsip kerja pemuatan kelas lalai Java, dan kami juga mengetahui model perwakilan induk. Setelah berkata begitu banyak, saya hampir terlupa tentang kucing jantan kami. Topik kami ialah mengapa pemuat Tomcat melanggar model perwakilan ibu bapa? Mari kita bercakap tentang pemuat kelas tomcat kami. 4 Bagaimanakah pemuat kelas Tomcat direka? Mula-mula, mari kita ajukan soalan:Adakah wajar jika Tomcat menggunakan mekanisme pemuatan kelas lalai?
🎜Mari kita fikirkan: Tomcat ialah bekas web, jadi apakah masalah yang perlu diselesaikannya:
Mari lihat soalan kami sekali lagi: Adakah boleh jika Tomcat menggunakan mekanisme pemuatan kelas lalai?
Jawapannya tidak. kenapa? Mari lihat masalah pertama Jika anda menggunakan mekanisme pemuat kelas lalai, anda tidak boleh memuatkan dua versi berbeza bagi pustaka kelas yang sama salinan.
Soalan kedua ialah pemuat kelas lalai boleh dilaksanakan kerana tanggungjawabnya adalah untuk memastikan keunikan. Soalan ketiga sama dengan soalan pertama. Mari kita lihat soalan keempat sekali lagi. Kami fikir bagaimana kita melaksanakan pengubahsuaian panas fail jsp (nama yang diberikan oleh poster itu sebenarnya fail kelas Jadi jika ia diubah suai, tetapi nama kelas masih sama, pemuat kelas akan terus Jika jsp sudah wujud dalam kawasan kaedah diambil, jsp yang diubah suai tidak akan dimuat semula.
Jadi apa yang patut kita buat? Kami boleh menyahpasang secara langsung pemuat kelas bagi fail jsp ini, jadi anda sepatutnya berfikir bahawa setiap fail jsp sepadan dengan pemuat kelas yang unik Apabila fail jsp diubah suai, pemuat kelas jsp dipunggah terus. Buat semula pemuat kelas dan muat semula fail jsp.
Jadi, bagaimanakah Tomcat melaksanakannya? Pasukan Tomcat yang hebat telah mereka bentuknya. Mari lihat lukisan reka bentuk mereka:
Kami melihat bahawa tiga pemuatan kelas pertama adalah konsisten dengan yang lalai CommonClassLoader, CatalinaClassLoader, SharedClassLoader dan WebappClassLoader adalah pemuat kelas Tomcat sendiri, masing-masing dalam kelas pemuat Web laluan pemuatan hanya boleh dilihat oleh Webapp semasa; /common/*
、/server/*
、/shared/*
(在tomcat 6之后已经合并到根目录下的lib目录下)和/WebApp/WEB-INF/*
中的Java类库。其中WebApp类加载器和Jsp类加载器通常会存在多个实例,每一个Web应用程序对应一个WebApp类加载器,每一个JSP文件对应一个Jsp类加载器。
commonLoader
:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;catalinaLoader
:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;sharedLoader
:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;WebappClassLoader
WebAppClassLoader boleh menggunakan kelas yang dimuatkan oleh SharedClassLoader, tetapi kejadian WebAppClassLoader individu diasingkan antara satu sama lain.
Skop pemuatan JasperLoader hanyalah fail .Class yang disusun oleh fail JSP ini Tujuan penampilannya adalah untuk dibuang: apabila bekas web mengesan bahawa fail JSP telah diubah suai, ia akan menggantikan tika JasperLoader semasa. , dan melaksanakan fungsi HotSwap fail JSP dengan mencipta pemuat kelas Jsp baharu.
Baiklah, setakat ini, kita sudah tahu mengapa tomcat direka dengan cara ini dan bagaimana ia direka Jadi, adakah tomcat melanggar model delegasi ibu bapa yang disyorkan oleh Java? Jawapannya: dilanggar.
Kami berkata sebelum ini:
Model delegasi induk memerlukan bahawa kecuali pemuat kelas permulaan peringkat atas, semua pemuat kelas lain harus dimuatkan oleh pemuat kelas induk mereka sendiri.
Jelas sekali, tomcat tidak dilaksanakan dengan cara ini Untuk mencapai pengasingan, tomcat tidak mematuhi konvensyen ini Setiap webappClassLoader memuatkan fail kelas dalam direktorinya sendiri dan tidak akan menyerahkannya kepada pemuat kelas induk.
Kami melanjutkan soalan: Apakah yang perlu kami lakukan jika Common ClassLoader tomcat mahu memuatkan kelas dalam WebApp ClassLoader? Selepas membaca kandungan sebelumnya tentang memusnahkan model delegasi induk, kami mempunyai idea yang jelas tindakan memuatkan.
Bukankah ia hebat?
Baiklah, akhirnya, kami faham mengapa Tomcat melanggar model delegasi induk, dan kami juga tahu cara pemuat kelas tomcat direka. Dengan cara ini, saya menyemak mekanisme pemuat kelas lalai Java, dan juga mempelajari cara memusnahkan mekanisme pemuatan kelas Java. Kali ini hasil tuaian bukan sedikit! ! !
Atas ialah kandungan terperinci Penemubual: Mengapakah pemuat kelas tomcat melanggar model perwakilan ibu bapa?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!