Home  >  Q&A  >  body text

java - spring ioc中为什么使用classloader,而不是Class.forName

阿神阿神2675 days ago498

reply all(1)I'll reply

  • 怪我咯

    怪我咯2017-04-18 10:53:03

    The difference between Class.forName and ClassLoader.loadClass

    Class loading

    In order to clarify the difference Class.forNameClassLoader.loadClass, first we need to understand the steps of class loading in JVM.
    Class loading can be divided into the following steps

    • Loading: Get the binary stream of the class through its fully qualified name, and then load it into the JVM

    • Verification: Ensure that the information contained in the byte stream of the Class file meets the requirements of the virtual machine and will not endanger the security of the virtual machine

    • Preparation: Allocate memory space for class variables and set the initial value of the class variable

    • Analysis

    • Initialization: Initialize fields and other resources according to user-specified code, executing static blocks.

    Class.forName

    When we pass:

    Class.forName("com.test.MyObj")

    When getting a Class, it is actually equivalent to calling Class.forName(className, true, currentLoader). The second parameter of this method indicates whether the class needs to be initialized. We set it to true, so when Class.forName obtains the Class object, it will automatically initialize the class.Class.forName(className, true, currentLoader), 这个方法的第二个参数表示是否需要初始化类. 我们设置为 true, 因此 Class.forName 获取到 Class 对象时, 会自动对类进行初始化的.
    并且 Class.forName 加载类的 ClassLoader 和调用 Class.forNameAnd Class.forName loads the ClassLoader of the class and the ClassLoader of the class where Class.forName is called Same.

    ClassLoader.loadClass

    Different from Class.forName, ClassLoader.loadClass does not initialize the class by default, that is, the initialization step of class loading is not executed, so Static code blocks in the class will not be executed.Class.forName 不同, 默认情况下 ClassLoader.loadClass 并不会初始化类, 即类加载的 初始化 步骤没有执行, 因此类中的静态代码块不会执行.
    并且使用 ClassLoader.loadClassAnd when using ClassLoader.loadClass, we can specify a different ClassLoader. For example:

    ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj");

    An example

    public class MyObj {
        static {
            System.out.println("MyObj class init.");
        }
    }
    public class Test implements Cloneable, Serializable {
        public static void main(String[] args) throws Exception {
            Class.forName("com.test.MyObj");
            // ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj");
        }
    }

    So in the above code, Class.forName("com.test.MyObj") 的调用会触发 MyObj 的静态代码块的执行, 而 ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj"); will not.

    What are the benefits of using it this way?

    My personal guess is that it should be related to Spring IoC's Lazy loading. In order to speed up the initialization, Spring IoC uses a lot of delayed loading technology. Using classloader does not need to execute the initialization code in the class, which can speed up the loading speed. The initialization work is left until the actual use of this class.

    reply
    0
  • Cancelreply