Analyse du code source Spring (processus de peignage)

Préface

Au cours du récent Nouvel An chinois, j'attends du travail à la maison. Je veux juste rester inactif. Il suffit de le recharger et de jouer avec le code source de Spring. Chaque fois que je mentionnerai Spring, IOC et AOP apparaîtront dans mon esprit.
Insérez la description de l'image ici
Premièrement, Je dois d'abord obtenir le CIO, puis comprendre l'AOP est encore plus simple!

CIO

Résumé
La plupart des gens savent que IOC est un conteneur, ce qui se traduit par une inversion de contrôle, ce qui signifie que nous créons manuellement des objets Java à gérer par Spring.
Insérez la description de l'image ici
Lorsque nous écrivons du code Java, nous avons besoin de nouveau. Le type d'objet dont nous avons besoin est le nouvel objet. Ce n'est pas un problème en soi, mais l'efficacité de l'opération de new à chaque fois est faible, ou la nouvelle opération est générée par nous-mêmes, nous nous-mêmes Pour générer cette nouvelle opération, si nous avons besoin de 10 objets, nous en avons besoin de 10 fois, et si nous en avons besoin de 100 fois, nous avons besoin de 100 fois, ce qui est relativement inefficace. Ensuite, nous pouvons laisser cette opération à Spring pour terminer, puis utilisez le conteneur Spring IOC pour terminer. Le conteneur doit stocker des objets Java, c'est-à-dire des Beans, puis ces Beans sont stockés dans une série de collections Java, telles que Map, List, etc., puis le principe d'implémentation sous-jacent du conteneur IOC est en fait la réflexion. @Autowired achève l'injection de haricots par réflexion

réflexion

public class UserService {
    
    
}

public class UserController {
    
    

    private UserService userService;

    public UserService getUserService() {
    
    
        return userService;
    }

    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }
}

public class MyTestList {
    
    

    @Test
    public void test() throws Exception {
    
    

        UserController userController=new UserController();
        Class<? extends UserController> clazz = userController.getClass();
        //创建对象
        UserService userService = new UserService();
        System.out.println(userService);
        //获取属性
        Field serviceField = clazz.getDeclaredField("userService");
        serviceField.setAccessible(true);//设置为可访问私有属性
        //只有通过方法才能够设置具体的属性值
        String name = serviceField.getName();
        //拼接方法的名称
        name = name.substring(0, 1).toUpperCase() + name.substring(1, name.length());
        String setMethodName = "set" + name;
        //通过方法注入属性的对象--这里还没注入,只是在构建入参和需要执行的方法
        Method method = clazz.getMethod("setUserService", UserService.class);
        //反射--也就是执行ssetUserService这个方法
        method.invoke(userController, userService);
        System.out.println(userController.getUserService());
    }
}

Implémentation de la réflexion @Autowired

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited/
@Documented
public @interface MyAutowired {
    
    
}


public class UserService {
    
    
}


public class UserController {
    
    

    @MyAutowired
    private UserService userService;

    public UserService getUserService() {
    
    
        return userService;
    }
}

public class Test2 {
    
    
    public static void main(String[] args)  {
    
    
        UserController userController=new UserController();
        Class<? extends UserController> clazz = userController.getClass();

        获取所有属性,并遍历
        Stream.of(clazz.getDeclaredFields()).forEach(field->{
    
    
            MyAutowired annotation = field.getAnnotation(MyAutowired.class);
            if (annotation!=null){
    
    
                field.setAccessible(true);
                //得到属性的类型
                Class<?> type = field.getType();
                try {
    
    
                    //创建这个属性类型的对象
                    Object o = type.newInstance();
                    //设置属性值
                    field.set(userController,o);
                } catch (InstantiationException e) {
    
    
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
    
    
                    e.printStackTrace();
                }
            }
        });
        System.out.println(userController.getUserService());
    }

}

Ce qui précède illustre deux cas de réflexion. Revenons maintenant à la partie IOC. IOC est un conteneur qui peut nous aider à terminer la création globale des objets. Après la création, nous pouvons obtenir directement des objets Java dans le conteneur IOC, ce qui est facile à comprendre. IOC est la façon dont nous obtenons des objets spécifiques. La compréhension simple de ces objets est qu'ils sont stockés dans la carte, et la valeur dans la carte peut être obtenue directement en fonction de la clé. Voyons ensuite comment il crée et stocke l'objet dans le CIO ! Ci-dessous se trouve l'organigramme général
Insérez la description de l'image ici

  • Le groupe ci-dessus de xml et d'annotation est généralement appelé BeanDefinition. BeanDefinition décrit une instance de bean avec des valeurs d'attribut, des valeurs de paramètre de constructeur et d'autres informations fournies par des implémentations spécifiques.

  • Lisez le Bean BeanDefinitionpour le stockage via cette interface BeanDefinitionReader

Après avoir lu les informations du Bean, nous commençons à l'instancier. Bien sûr, Spring n'est pas seulement un framework, mais aussi une écologie. Afin de prendre en charge des applications de couche supérieure plus flexibles et plus efficaces, pour Spring, nous devons envisager davantage l'évolutivité et l'extensibilité., l'extensibilité et l'extensibilité rendent impossible de simplement instancier directement ici!

  • Lorsque l'objet Bean est créé, il est créé BeanFunctionen obtenant le BeanDefinition et en utilisant la réflexion.
  • BeanFactoryPostProcessor, Cette interface est héritée pour terminer l'opération d'expansion. Par exemple, lorsque nous lisons le Bean, nous devons appeler une méthode spécifique, puis nous pouvons utiliser cette interface pour terminer
  • 实例化和初始化, L'instanciation consiste à appeler la méthode de construction correspondante, puis à ouvrir un espace mémoire, mais les propriétés à l'intérieur n'ont pas terminé l'opération d'affectation, puis une fois l'instanciation terminée, une série d'opérations d'initialisation doivent être terminées, puis instancier ici - > initialize—> Lorsque l'initialisation est terminée, alors AOP est formé, qui comprend également BeanPostProcessorcette interface
  • EnvironmentUne série de valeurs d'environnement système sont encapsulées dans cette interface et vous pouvez les appeler directement si vous avez besoin de les obtenir dans le code.

Différence entre BeanFactory et FactoryBean

Il existe deux façons de créer des objets, l'une est BeanFactory et l'autre est FactoryBean. En général, nos objets normaux sont créés avec BeanFactory. Pour certains objets spéciaux, FactoryBean est nécessaire lorsqu'une personnalisation est requise. Pour terminer, vous pouvez utiliser getObject pour personnaliser le traitement lors de l'utilisation de FactoryBean pour l'implémenter, et l'implémenter comme vous le souhaitez, et feindre utilise cette méthode d'implémentation.

public class MyFactoryBean implements FactoryBean {
    
    
    @Override
    public Object getObject() throws Exception {
    
    
        TestMain testMain = new TestMain();
        System.out.println("----------一系列而外的定制操作-----------");
        //以直接通过getObject方法来完成定制化的Bran,无需使用BeanFactory一步一步按流程生成!
        return testMain;
    }
   
    @Override
    public Class<?> getObjectType() {
    
    
        return null;
    }

    @Override
    public boolean isSingleton() {
    
    
        return true;
    }
}

Je suppose que tu aimes

Origine blog.csdn.net/CSDN877425287/article/details/113760260
conseillé
Classement