美文网首页
springboot自动装配

springboot自动装配

作者: 小方块886 | 来源:发表于2021-02-22 23:31 被阅读0次

    springboot自动装配重要注解

    1. @EnableAutoConfiguration @Import
      作用:将发现的类交给spring管理,先看一下@import注解在哪里用到
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class) // springboot启动类中@EnableAutoConfiguration注解中
    public @interface EnableAutoConfiguration { // springboot启动类@SpringBootApplication注解中
    

    这里我们开始试验一下import注解的作用
    先创建一个demot类

    //@Import(User.class) // 先注释这个注解运行下面的结果
    @Configuration // 声名配置类的注解
    public class ImportTestDemo {
        public static void main(String[] args) {
            // 这个我们可以理解为spring通过注解方式发现并注册bean工厂的对象
            AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ImportTestDemo.class);
            // 所有对象名字集合
            String[] names = ac.getBeanDefinitionNames();
            for (String name : names) {
                // 打印看下bean工厂里面有那些对象
                System.out.println(name);
                System.out.println("----------------");
            }
        }
    
    }
    

    看下运行结果,只有我们声名的配置类打应出来了

    importTestDemo
    ----------------
    

    接下来我们用上import注解,并运行一下

    @Import(User.class) // User是我自定义的一个实体
    @Configuration // 声名配置类的注解
    public class ImportTestDemo {
        public static void main(String[] args) {
            // 这个我们可以理解为spring通过注解方式发现并注册bean工厂的对象
            AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ImportTestDemo.class);
            // 所有对象名字集合
            String[] names = ac.getBeanDefinitionNames();
            for (String name : names) {
                // 打印看下bean工厂里面有那些对象
                System.out.println(name);
                System.out.println("----------------");
            }
        }
    
    }
    

    这个时候我们发现User对象也从spring容器中打印出来了,证明Impot注解有效果

    importTestDemo
    ----------------
    com.example.springbootredisson.bean.User
    ----------------
    

    了解一下AutoConfigurationImportSelector的类,在第一个源码图中@Import中注解属性能看到
    我们自己来实现一下ImportSelect

    public class ImportSelectDemo implements ImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            // 这里写死试试效果,当然spring有更优雅的代码检测出项目中的类
            return new String[]{Goods.class.getName(), User.class.getName()};
        }
    }
    
    @Configuration
    @Import(ImportSelectDemo.class) // 自己实现的ImportSelect类
    public class ImportTestDemo {
    
        public static void main(String[] args) {
            AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ImportTestDemo.class);
            String[] names = ac.getBeanDefinitionNames();
            for (String name : names) {
                System.out.println(name);
                System.out.println("----------------");
            }
        }
    
    }
    
    importTestDemo
    ----------------
    com.example.springbootredisson.bean.Goods
    ----------------
    com.example.springbootredisson.bean.User
    ----------------
    

    到这里看到@Import和就是发现并注册类到spring容器中的作用
    @EnableAutoConfiguration 注解作用就是将发现的类注册到ioc容器中,通过实现AutoConfigurationImportSelector这个类来发现并注册。下面再看来看importSelect这个类

        @Override
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            if (!isEnabled(annotationMetadata)) {
                return NO_IMPORTS;
            }
                    // 通过配置文件spring.factories发现类
            AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
                    // 这里的返回值就是类对象的路径
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    

    在往下看看getAutoConfigurationEntry(annotationMetadata)这个方法

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
            if (!isEnabled(annotationMetadata)) {
                return EMPTY_ENTRY;
            }
            AnnotationAttributes attributes = getAttributes(annotationMetadata);
            // 获取spring.factories中的类路径 这里是springboot自动装配的主要方法
            List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
            configurations = removeDuplicates(configurations);
            Set<String> exclusions = getExclusions(annotationMetadata, attributes);
            checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = getConfigurationClassFilter().filter(configurations);
            fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationEntry(configurations, exclusions);
        }
    

    打开mybaties的starter看看是否有spring.factory配置文件


    Snipaste_2021-02-24_23-18-18.png

    结论:springboot读取spring.factories配置文件,读取配置文件加载类到ioc中,这就是第三方starter的原理,也就是springboot自动装配的原理。
    因此我们在springboot中只需要引入第三方starter 就能开箱即用,同理我们可以自己打包一个starter给另外一个项目
    使用如何自己写一个starter,这个很简单,em...百度一下就好了

    相关文章

      网友评论

          本文标题:springboot自动装配

          本文链接:https://www.haomeiwen.com/subject/iqdlfltx.html