• SpringBoot SpringBoot 原理篇 1 自动配置 1.8 bean 的加载方式【六】


    SpringBoot

    【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】

    SpringBoot 原理篇

    1 自动配置

    1.8 bean 的加载方式【六】
    1.8.1 ImportSelector

    OK,上一节又说完了第五种

    使用上下文对象在容器初始化完毕后注入bean

    在这里插入图片描述

    下面就来说说第六种

    第六种方式平时咱们自己用的少,但是在框架内部大量使用

    先来一个全新的类

    package com.dingjiaxiong.bean;
    
    import org.springframework.context.annotation.ImportSelector;
    import org.springframework.core.type.AnnotationMetadata;
    
    /**
     * ClassName: MyImportSelector
     * date: 2022/10/24 15:39
     *
     * @author DingJiaxiong
     */
    
    public class MyImportSelector implements ImportSelector {
    
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            return new String[]{"com.dingjiaxiong.bean.Dog"};
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    数组中是要加载bean 的全路径名

    再来一个新的配置类

    package com.dingjiaxiong.config;
    
    import com.dingjiaxiong.bean.Dog;
    import com.dingjiaxiong.bean.MyImportSelector;
    import org.springframework.context.annotation.Import;
    
    /**
     * ClassName: SpringConfig6
     * date: 2022/10/24 14:52
     *
     * @author DingJiaxiong
     */
    
    @Import(MyImportSelector.class)
    public class SpringConfig6 {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    最后来个运行类

    package com.dingjiaxiong.app;
    
    import com.dingjiaxiong.bean.Cat;
    import com.dingjiaxiong.bean.Mouse;
    import com.dingjiaxiong.config.SpringConfig4;
    import com.dingjiaxiong.config.SpringConfig6;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * ClassName: App6
     * date: 2022/10/24 13:42
     *
     * @author DingJiaxiong
     */
    
    public class App6 {
    
        public static void main(String[] args) {
    
            ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig6.class);
    
            String[] names = ctx.getBeanDefinitionNames();
            for (String name : names) {
                System.out.println(name);
            }
            System.out.println("=========================");
    
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    OK,直接运行

    在这里插入图片描述

    OK, 效果很明显,已经上来了

    还可以写多个

    在这里插入图片描述

    没毛病

    加载就是这样了,难免会有人想问,为嘛要折腾这?

    这种方式的关键

    在这里插入图片描述

    在于这个东西

    Metadata 元数据:

    举个例子,我们造了一个数据库、表,表里面有数据,那么这个数据表的信息在哪儿描述?

    还得有另外一张表来描述这张表的结构,那这另外这张表就可以称为被描述表的元数据

    还可以有元元数据、元元元数据…【数据库中有四层】

    在我们这儿,元数据就是往上追溯一下

    【这个东西有什么用?】

    修改一下

    package com.dingjiaxiong.bean;
    
    import org.springframework.context.annotation.ImportSelector;
    import org.springframework.core.type.AnnotationMetadata;
    
    /**
     * ClassName: MyImportSelector
     * date: 2022/10/24 15:39
     *
     * @author DingJiaxiong
     */
    
    public class MyImportSelector implements ImportSelector {
    
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    
            System.out.println(importingClassMetadata.getClassName());
    
            return new String[]{"com.dingjiaxiong.bean.Dog"};
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    先拿个classname 看看

    在这里插入图片描述

    意思就是 importingClassMetadata 这个形参描述的是 SpringConfig6

    简单的说,

    在这里插入图片描述

    加载的是谁,描述的就是谁

    再来

    System.out.println(importingClassMetadata.hasAnnotation("org.springframework.context.annotation.Configuration"));
    
    • 1

    这个意思就是描述的那个东西上面有没有Configuration 注解

    直接看看

    在这里插入图片描述

    如果我注掉

    在这里插入图片描述

    这样就false了

    所以现在就可以明确了 importingClassMetadata 这个指的就是它那个类出现在谁上面

    在这里插入图片描述

    意思就是SpringConfig6 就是它对应的元数据

    再来一个

    在这里插入图片描述

    现在我想知道,它有没有加basePackages 这个属性

    package com.dingjiaxiong.bean;
    
    import org.springframework.context.annotation.Import;
    import org.springframework.context.annotation.ImportSelector;
    import org.springframework.core.type.AnnotationMetadata;
    
    import java.util.Map;
    
    /**
     * ClassName: MyImportSelector
     * date: 2022/10/24 15:39
     *
     * @author DingJiaxiong
     */
    
    public class MyImportSelector implements ImportSelector {
    
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    
            System.out.println("===========================");
    
            System.out.println(importingClassMetadata.getClassName());
            System.out.println(importingClassMetadata.hasAnnotation("org.springframework.context.annotation.Configuration"));
            Map<String, Object> attributes = importingClassMetadata.getAnnotationAttributes("org.springframework.context.annotation.ComponentScan");
    
            System.out.println(attributes);
            
            System.out.println("===========================");
            return new String[]{"com.dingjiaxiong.bean.Dog"};
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    OK,直接运行

    在这里插入图片描述

    OK, 没啥毛病

    到现在大概就知道了,我们可以利用这个东西去做一系列的判定,ImportSelector 的意义就在于我们可以进行各种条件的判定,判定完毕后,决定是否装载指定的bean

    举个栗子

    package com.dingjiaxiong.bean;
    
    import org.springframework.context.annotation.Import;
    import org.springframework.context.annotation.ImportSelector;
    import org.springframework.core.type.AnnotationMetadata;
    
    import java.util.Map;
    
    /**
     * ClassName: MyImportSelector
     * date: 2022/10/24 15:39
     *
     * @author DingJiaxiong
     */
    
    public class MyImportSelector implements ImportSelector {
    
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    
            boolean flag = importingClassMetadata.hasAnnotation("org.springframework.context.annotation.Configuration");
            if (flag){
                return new String[]{"com.dingjiaxiong.bean.Dog"};
            }
            return new String[]{"com.dingjiaxiong.bean.Cat"};
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    判定运行结果

    在这里插入图片描述

    就是这样,意思就是这个东西不仅能够加载bean,它还可以进行条件判定、然后控制加载谁

    OK,回顾一下

    导入实现了ImportSelector接口的类,实现对导入源的编程式处理

    在这里插入图片描述

    相当于现在谁导入这个类,它就可以查谁的户口

    SpringConfig6 导入了它,它就可以查SpringConfig6 的户口

    在这里插入图片描述

    OK

  • 相关阅读:
    IDC报告:国内游戏云市场,腾讯云用量规模位列第一
    milvus使用python调用时连接失败 pymilvus.exceptions.MilvusException
    基于R语言、MATLAB、Python机器学习方法与案例分析
    递归 Stream流式 自关联递归
    细说 PDF 里的“秘密”——如何标记密文
    驱动day4
    【C语言】【结构体的位段】位段的内存分配及注意事项
    java基础之泛型
    hadoop配置
    【操作系统】进程是如何调度的?
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/128048675