当前位置:网站首页>JVM -- custom class loader
JVM -- custom class loader
2022-07-28 22:39:00 【Eighteen movements of Tathagata divine palm】
0. Why do I need a custom class loader
Most of the custom classloader articles on the Internet , Almost all of them stick a piece of implementation code , Then analyze oneortwo sentences of customization ClassLoader Principle . But I think we have to figure out why we need custom loaders first , Because if you don't understand its function , It is obviously confusing to learn it .
First, introduce the application scenarios of custom classes :
(1) encryption :Java Code can be easily Decompile , If you need to encrypt your code to prevent decompilation , You can use some kind of encryption Algorithm encryption , Class can't be used after encryption Java Of ClassLoader To load the class , Now you need to customize ClassLoader Decrypt the class when loading it , Then load .
(2) Loading code from non-standard sources : If your bytecode is in the database 、 Even in the clouds , You can customize the class loader , Load the class from the specified source .
(3) The comprehensive application of the above two situations in practice : For example, your application needs to be transmitted through the network Java Class bytecode , For safety reasons , These bytecodes are encrypted . At this time, you need to customize the classloader to read the encrypted bytecode from a certain network address , Then decryption and verification , Finally, the definition of Java Classes running in a virtual machine .
1. Parent delegation model
In the realization of their own ClassLoader Before , Let's first understand how the system loads classes , Then I have to introduce the implementation process of the parental delegation model .
// The working process source code of the parental delegation model
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
}
catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
// The parent class loader cannot complete the class load request
}
if (c == null) {
// If still not found, then invoke findClass in order to find the class
// The child loader performs class loading
c = findClass(name);
}
}
if (resolve) {
// Determine whether the link process is needed , Parameters of the incoming
resolveClass(c);
}
return c;
}
The working process of the parent delegation model is as follows :
(1) The current class loader queries whether the class has been loaded from its loaded class , If it is already loaded, it will directly return the originally loaded class .
(2) If not found , Delegate the parent class loader to load ( Such as code c = parent.loadClass(name, false) Shown ). The parent loader will use the same strategy , Check whether the class you have loaded contains this class , Go back when you have , There is no load on the parent class of the delegate parent class , Until you start the class loader . Because if the parent loader is empty , This means that the startup class loader is used as the parent loader to load .
(3) If the loader fails to start ( For example, in $JAVA_HOME/jre/lib We didn't find the class), An exception is thrown ClassNotFoundException, Then call the of the current loader findClass() Method to load .
Benefits of the parental delegation model :
(1) Mainly for safety , Avoid dynamic substitution of classes written by users themselves Java Some of the core classes of , such as String.
(2) At the same time, it also avoids the repeated loading of classes , because JVM There are different kinds in the middle , It's not just about class names , same class The documents are different ClassLoader Loading is just two different classes .
2. Custom class loaders
(1) From the above source code , call loadClass Will first load in the parent loader according to the delegation model , If the load fails , The current loader's findClass To finish loading .
(2) Therefore, our custom classloader only needs to inherit ClassLoader, And cover findClass Method , Here's a practical example , In this example, we use the custom Class loading To load what we prepared in advance class file .
2.1 Customize a People.java Class as an example
public class People {
// It's written in Notepad , In use javac The command line is compiled as class file , Put it in d Under the root directory
private String name;
public People() {
}
public People(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "I am a people, my name is " + name;
}
}
2.2 Custom class loaders
Customize a class loader , Need to inherit ClassLoader class , And implement findClass Method . among defineClass Method can convert a file composed of binary stream bytes into a java.lang.Class( As long as the contents of the binary byte stream match Class Document specification ).
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
public class MyClassLoader extends ClassLoader
{
public MyClassLoader()
{
}
public MyClassLoader(ClassLoader parent)
{
super(parent);
}
protected Class<?> findClass(String name) throws ClassNotFoundException
{
File file = new File("D:/People.class");
try{
byte[] bytes = getClassBytes(file);
//defineClass Method can convert a file composed of binary stream bytes into a java.lang.Class
Class<?> c = this.defineClass(name, bytes, 0, bytes.length);
return c;
}
catch (Exception e)
{
e.printStackTrace();
}
return super.findClass(name);
}
private byte[] getClassBytes(File file) throws Exception
{
// Read in here .class Bytes of , So use a byte stream
FileInputStream fis = new FileInputStream(file);
FileChannel fc = fis.getChannel();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
WritableByteChannel wbc = Channels.newChannel(baos);
ByteBuffer by = ByteBuffer.allocate(1024);
while (true){
int i = fc.read(by);
if (i == 0 || i == -1)
break;
by.flip();
wbc.write(by);
by.clear();
}
fis.close();
return baos.toByteArray();
}
}
2.3 Use in the main function
MyClassLoader mcl = new MyClassLoader();
Class<?> clazz = Class.forName("People", true, mcl);
Object obj = clazz.newInstance();
System.out.println(obj);
System.out.println(obj.getClass().getClassLoader());// Print out our custom class loader
2.4 Running results
So far about customization ClassLoader The content of is summarized .
边栏推荐
- Sword finger offer II 054. Sum of all values greater than or equal to nodes (medium binary search tree DFS)
- Vscode ROS configuration GDB debugging error record
- Win11 how to open software notification
- Use REM to make the font size adaptive to the screen
- MySQL command (add, delete, check and modify)
- Static route and default route experiment
- 105. Construct binary tree from preorder and inorder traversal sequence (medium binary tree DFS hash table binary tree)
- Soft exam network engineer
- winServer运维技术栈
- Research cup element recognition multi label classification task based on ernie-3.0 cail2019 method
猜你喜欢
Win11 how to open software notification
[connect your mobile phone wirelessly] - debug your mobile device wirelessly via LAN
软考网络工程师
Sword finger offer II 052. flatten binary search tree (simple binary search tree DFS)
Overall introduction of Ruiji takeout project
php二维数组如何删除去除第一行元素
JVM——自定义类加载器
STM32CUBEIDE(10)----ADC在DMA模式下扫描多个通道
Ngrok intranet penetration
STM32 - external interrupt application (exti) (use cubemx to configure interrupts)
随机推荐
STM32 - reset and clock control (cubemx for clock configuration)
PHP库neo4j怎么安装及使用
Changes in the history of oscilloscope development
There will be a black line on the border when the button in the wechat applet is clicked
Use REM to make the font size adaptive to the screen
Ngrok intranet penetration
Paddlenlp is based on ernir3.0 text classification. Take the traditional Chinese medicine search and retrieval semantic map classification (kuake-qic) as an example [multi classification (single label
AWK空行过滤
PaddleNLP基于ERNIR3.0文本分类以CAIL2018-SMALL数据集罪名预测任务为例【多标签】
842. 排列数字
微信小程序使用canvas绘图,圆形头像,网络背景图,文字,虚线,直线
Excel-vba quick start (XIII. Common usage of date)
Jianzhi offer II 062. implement prefix tree (medium design dictionary tree prefix tree string)
mysql8.0无法给用户授权或提示You are not allowed to create a user with GRANT的问题
What are the main functions and uses of LCR tester
npm ERR code ETIMEDOUT npm ERR syscall connect npm ERR errno ETIMEDOUT npm ERR network reques...
Target segmentation learning
Static details of static members
JS获取当前时间(年月日时分秒)
Using nodejs to operate MySQL