Maison  >  Questions et réponses  >  le corps du texte

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

阿神阿神2743 Il y a quelques jours528

répondre à tous(1)je répondrai

  • 怪我咯

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

    La différence entre Class.forName et ClassLoader.loadClass

    Chargement des classes

    Afin de comprendre la différence entre Class.forName et ClassLoader.loadClass, nous devons d'abord comprendre les étapes de chargement des classes dans JVM
    Le chargement des classes peut être divisé en les étapes suivantes

    .
    • Chargement : récupérez le flux binaire de la classe via son nom complet, puis chargez-le dans la JVM

    • Vérification : assurez-vous que les informations contenues dans le flux d'octets du fichier Class répondent aux exigences de la machine virtuelle et ne mettront pas en danger la sécurité de la machine virtuelle

    • Préparation : Allouer de l'espace mémoire pour les variables de classe et définir la valeur initiale de la variable de classe

    • Analyse

    • Initialisation : initialisez les champs et autres ressources selon le code spécifié par l'utilisateur, en exécutant des blocs statiques.

    Classe.forName

    Quand on passe :

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

    est utilisé pour obtenir une classe, cela équivaut en fait à appeler Class.forName(className, true, currentLoader). Le deuxième paramètre de cette méthode indique si la classe doit être initialisée à true, donc lorsque Class.forName obtient. l'objet Class, ce sera La classe est automatiquement initialisée.
    Et le ClassLoader de la classe chargée par Class.forName est le même que le ClassLoader de la classe où Class.forName est appelé.

    ClassLoader.loadClass

    est différent de Class.forName. Par défaut, ClassLoader.loadClass n'initialise pas la classe, c'est-à-dire que l'étape 初始化 de chargement de la classe n'est pas exécutée, donc le bloc de code statique de la classe ne sera pas exécuté.
    et utilisez ClassLoader.loadClass, nous pouvons spécifier différents ClassLoader Par exemple :

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

    Un exemple

    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");
        }
    }

    Dans le code ci-dessus, l'appel de Class.forName("com.test.MyObj") déclenchera l'exécution du bloc de code statique de MyObj, mais ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj"); ne le fera pas.

    Quels sont les avantages de l’utiliser de cette façon ?

    Mon hypothèse personnelle est que cela devrait être lié au chargement paresseux de Spring IoC. Afin d'accélérer l'initialisation, Spring IoC utilise de nombreuses technologies de chargement retardé. L'utilisation de classloader n'a pas besoin d'exécuter le code d'initialisation dans la classe. ce qui peut accélérer le chargement. Le travail d'initialisation de la classe est laissé jusqu'à ce que la classe soit réellement utilisée.

    répondre
    0
  • Annulerrépondre