The method of loading various resources (classes, files, web resources) with ClassLoader in Java

lassLoader mainly provides services for class requests. When JVM needs a certain class, it asks ClassLoader for this class according to its name, and then ClassLoader returns the class object of this class.

ClassLoader is responsible for loading all resources of the system (Class, files, pictures, byte streams from the network, etc.), and loads resources into the JVM through ClassLoader. Each class has a reference to its own ClassLoader.

 

1. Several ways to get ClassLoader

ClassLoader can be obtained in the following three ways:


 
  1. this.getClass.getClassLoader();   // Use the ClassLoader of the current class   
  2.   
  3. Thread.currentThread().getContextClassLoader();   // Use the current thread's ClassLoader   
  4.   
  5. ClassLoader.getSystemClassLoader();   // Use the system ClassLoader, which is the ClassLoader used by the entry point of the system.  

 

Note: The system ClassLoader is not the same as the root ClassLoader. The system ClassLoader under the JVM is usually the App ClassLoader.

 

2. Several methods of loading resources with ClassLoader 

All resources are loaded into the JVM through ClassLoader, so of course ClassLoader can be used when loading resources, but different resources can also be loaded in other ways, for example, classes can be directly new, and files can be directly IO Wait.

 

2.1 How to load classes

Assuming that there are class A and class B, A needs to instantiate B in its method, and there are three possible ways to load the class. In the case of loading classes, the user needs to know the full name of class B (including the package name, eg "com.alexia.B") 

1. Use the Class static method Class.forName  

 


 
  1. Class cls = Class.forName("com.alexia.B");  
  2.  B b = (B)cls.newInstance();  

 

2. Using ClassLoader  

 


 
  1. /* Step 1. Get ClassLoader */  
  2. ClassLoader cl =  this.getClass.getClassLoader();;   // How to get ClassLoader reference 1  
  3.   
  4. /* Step 2. Load the class */  
  5. Class cls = cl.loadClass( "com.alexia.B");  // Use the ClassLoader obtained in the first step to load B  
  6.      
  7. /* Step 3. new instance */  
  8. B b = (B)cls.newInstance();  // a class with B gets an instance of B  

 

3. Direct new 

 


 
  1. B b = new B();  

 

Note: Some people may think in their hearts that we will choose the simplest third method for the loading method of classes, and the first two methods are completely redundant.

In fact, the method of direct new is also limited. For the simplest example: How can a class with a package name in Java refer to a class in the default package? Of course, this is because a class with a package name cannot directly use new to refer to a class in the default package, so what should we do? The answer is to use the reflection mechanism, which is to use the first method to load the class (see here for details ). Also, creating an instance of a class with new() is different from creating an instance of a class with newInstance(). The main differences are briefly described as follows:

From the JVM's point of view, when we use the keyword new to create a class, the class can be unloaded. But when using the newInstance() method, you must ensure that:

(1) This class has been loaded;

(2) The class is already linked (that is, allocating storage space for static fields, and resolving all references to other classes created by this class if necessary). It is the static method forName() of Class that completes the above two steps. This static method calls the startup class loader, that is, the loader that loads the javaAPI.

It can be seen that newInstance() actually decomposes the new method into two steps, that is, first call the Class loading method to load a class, and then instantiate it. The benefits of this step-by-step approach are obvious. We can get better flexibility when calling the static loading method forName of the class, which provides a means of decoupling.

 

2.2 How to load files (such as configuration files, etc.)

Suppose you want to read the file sys.properties in the folder /com/alexia/config in the com.alexia.A class. You can read the file through an absolute path or a relative path. The absolute path is very simple. It starts with the disk number under Windows. , starting with "/" under Unix. For the relative path, the relative value is relative to the ClassLoader, because the ClassLoader is a tree, so the relative path and any ClassLoader on the ClassLoader tree can find the file after relative comparison, then the file can be found. There are three ways to load files:

1. Read directly with IO stream 

 


 
  1. /** 
  2.  * Assuming the current location is "C:/test", run A "java com.aleixa.A" by executing the following command 
  3.  * 1. The absolute path can be used in the program. The absolute path under Windows starts with the disk number, and under Unix it starts with "/" 
  4.  * 2. You can also use a relative path, there is no "/" in front of the relative path 
  5.  * Since we are executing the program in the "C:/test" directory, the program entry point is "C:/test", and the relative path is 
  6.  * 是 "com/alexia/config/sys.properties" 
  7.  * (In the example, the ClassLoader of the current program is App ClassLoader, system ClassLoader = current 
  8.  * ClassLoader of the program, the entry point is "C:/test") 
  9.  * For the ClassLoader tree, if the file is under jdk lib, or under jdk lib/ext, or in environment variables, 
  10.  * can be found through the relative path "sys.properties", the files under lib are found first 
  11.  */  
  12. File f =  new File( "C:/test/com/aleixa/config/sys.properties");  // use absolute path  
  13. //File f = new File("com/alexia/config/sys.properties"); // use relative path  
  14. InputStream is = new FileInputStream(f);    

 

2. Using ClassLoader  

 


 
  1. /** 
  2.  * Because there are 3 ways to get ClassLoader, corresponding to the following 3 ClassLoader methods to read files 
  3.  * The path used is a relative path relative to the point of this ClassLoader, only relative paths can be used here 
  4.  */  
  5. InputStream is = null;  
  6. is = this.getClass().getClassLoader().getResourceAsStream(  
  7.        "com/alexia/config/sys.properties"); //方法1  
  8. //is = Thread.currentThread().getContextClassLoader().getResourceAsStream(  
  9.        "com/alexia/config/sys.properties"); //方法2  
  10. //is = ClassLoader.getSystemResourceAsStream("com/alexia/config/sys.properties"); //方法3   

 

3. Using ResourceBundle 

 


 
  1. ResourceBundle bundle = ResourceBundle.getBoundle("com.alexia.config.sys");   

 

This usage is usually used to load the user's configuration file. For more detailed usage of ResourceBundle, please refer to other documents.

Note: If it is a property configuration file, you can also read the content into Properties through java.util.Properties.load(is). Properties default that the encoding of is is ISO-8859-1. If the configuration file is not in English, it may appear garbled problem.

 

Summary: There are three ways to load files as follows 

    1. Absolute path ---> IO
    2. Relative path ---> IO 
                      ---> ClassLoader 
    3. Resource bundle ---> ResourceBundle 

 

2.3 Loading method of web resources

Of course, ClassLoader can also be used to load resources in web applications, but ServletContext is more commonly used. The following is the web directory structure 
    ContextRoot 
       |- JSP, HTML, Image and other files 
        |- [WEB-INF] 
              |- web .xml 
              |- [lib] JAR file used by Web 
                |- [classes] Class file 

User program is usually in the classes directory, if you want to read the files in the classes directory, you can use ClassLoader, if you want to read other files, Generally use ServletContext.getResource().

If the ServletContext.getResource(path) method is used, the path must start with "/", and the path is interpreted as a path relative to the ContextRoot. The method of loading files here is different from that of ClassLoader, for example "/WEB-INF/web.xml" ,"/download/WebExAgent.rar"

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325298423&siteId=291194637