栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java > SpringBoot

Spring-boot @EnableAutoConfiguration源码分析

SpringBoot 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring-boot @EnableAutoConfiguration源码分析

@EnableAutoConfiguration作用:从classpath中搜索所有的meta-INF/spring.factories配置文件,然后将其中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的value加载到spring容器中

首先我们来做一个小实验:
1、创建一个spring项目jianshu-starter


    4.0.0

    com.bamu.jianshu
    jianshu-starter
    1.0-SNAPSHOT

    jianshu-starter
    The first Spring Boot project

    
        UTF-8
        1.8
        1.8
    

    
        
            org.springframework
            spring-context
            4.3.11.RELEASE
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
            
                org.apache.maven.plugins
                maven-compiler-plugin
                
                    1.8
                    1.8
                
            
        
    

2、编写configuration类,注入到spring容器中

@Configurationpublic class RunnableConfiguration {    @Bean
    public Runnable runnable() {        return () -> {};
    }
}

3、创建一个spring-boot项目blog,引入刚刚创建的外部项目jianshu-starter

//...
      com.bamu.jianshu
      jianshu-starter
      1.0-SNAPSHOT//...

4、在blog项目中编写启动类BlogApplication

@SpringBootApplicationpublic class BlogApplication {    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(BlogApplication.class, args);        //获取jianshu-starter项目中定义的bean runnable
        System.out.println(context.getBean("runnable").getClass().getName());
        context.close();
    }
}

5、启动


console result


咦?@SpringBootApplication注解中不是为我们配置了@EnableAutoConfiguration了吗?为什么这里获取不到外部项目注入到spring容器中的bean呢?


为了解答这个疑惑,我们查阅@EnableAutoConfiguration注解中import进去的Selector的源码,追溯到AutoConfigurationimportSelector这个类后,我们发现了getCandidateConfigurations(Annotationmetadata metadata, AnnotationAttributes attributes)这个方法。

getCandidateConfigurations方法


红框中的英文翻译后意思为:在meta-INF / spring.factories中找不到自动配置类。 如果您使用自定义打包,请确保文件正确无误。


继续带着疑惑,我们试着点进loadFactoryNames这个方法中去一探究竟:

loadFactoryNames方法


噢,原来,这个方法通过是ClassLoader,去我们的classpath目录下的meta-INF/spring.factoried文件中去查找以EnableAutoConfiguration这个类的全类名为key的值,然后把它们add到一个集合当中return出去。看完这个方法的源码后,我们回到上一个截图getCandidateConfigurations方法的源码,发现他在做了一个非空校验后,接着往上层返回。那我们找到调用getCandidateConfigurations方法的代码看看。



selectimports方法


我们追溯到了selectimports这个方法。阅读过Spring-Boot之@Enable*注解的工作原理这篇文章的读者肯定一下就看明白了,噢,原来这个方法获取到了List configurations这个集合后,通过removeDuplicates方法做了去重、通过sort方法做了排序、通过getExclusions这个方法做了排除(那我们排除的依据从哪来呢?大家可以打开@EnableAutoConfiguration注解的源码一看便知,该注解给我们提供了两种方式排除我们不想注入到spring容器中的bean)......最后将configurations这个集合转为String[]返回,通过推荐的文章我们知道,selectimports()方法返回出去的数组是会被spring容器托管的,这下我们全知道了:
在springboot项目中,其他包下自动装配的bean,是需要在classpath下的meta-INF/spring.factories文件中配置,才能被spring容器注入


so,我们按照springboot的要求,创建一个spring.factories并配置我们需要获取的bean runnable


spring.factories


meta-INF/spring.factories


提醒一下:由loadFactoryNames和selectimports方法的源码我们发现,key必须是EnableAutoConfiguration注解的全类名,value必须是你想自动装配的bean的全类名
再执行BlogApplication类试一试:


console result

完美地获取到了runnable这个对象

另外,拓展一下springboot为我们提供的starter包如何实现开箱即用。事实上,我们看到的springboot提供的starter包,都引用了很多我们比较熟悉的jar包,它也是通过我在上文中介绍的方式,将它想要注入的bean,配置到spring.factories文件中。例如:

spring-boot-autoconfiguration


我们打开spring.factories文件看一看

spring.properties文件冰山一角


看看,spring-boot-autoconfiguration这个项目注入了这么多其他项目的bean。

以上,就是Spring-boot @EnableAutoConfiguration源码分析的全部内容,望读者带着批判的心态阅读我的文章,发现错误,麻烦直接评论,共同学习,共同进步。



作者:八目朱勇铭
链接:https://www.jianshu.com/p/c1c2443ed43b


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/235501.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号