• SpringBoot约定大于配置


    什么是约定大于配置

    "约定大于配置"(Convention Over Configuration)是一种理念,旨在通过默认约定和规则来减少开发人员需要做的配置工作。在Spring Boot框架中,这一原则得到了充分应用,帮助开发者更快地构建高效的应用程序

    SpringBoot如何实现约定大于配置

    @SpringBootApplication

    在springboot项目中,我们会使用@SpringBootApplication注解在启动类上,它提供了相当多的便利性,帮助我们完成了当前启动类目录下的组件扫描和自动配置,其源码如下

     可以看到它是一个组合注解,相当于声明了@Configuration、@EnableAutoConfiguration和@ComponentScan,而自动装配实现的秘密就在@EnableAutoConfiguration注解上

    @EnableAutoConfiguration

     

     查看@EnableAutoConfiguration源码,发现它注入了一个AutoConfigurationImportSelector类型的bean,继续跟进

    AutoConfigurationImportSelector

    我们查看一下AutoConfigurationImportSelector类关系图

    AutoConfigurationImportSelector是做什么的呢?该类上的javadoc有这么一句话,“DeferredImportSelector to handle auto-configuration”,deferred的意思是推迟的,意为处理自动装配的推迟的ImportSelector

    DeferredImportSelector 是 ImportSelector的子类,它在所有@Configuration bean都处理完毕后运行。而AutoConfigurationImportSelector实现了DeferredImportSelector接口,并实现了该接口的selectImports方法

    查看selectImports方法发现,内部的getAutoConfigurationEntry方法就返回了要装配的@Configuration类

    其中最关键的是getCandidateConfigurations方法,源码如下

    这里调用了SpringFactoriesLoader.loadFactoryNames返回所有的自动装配类,这个方法的第一个入参就是EnableAutoConfiguration.class,第二个入参是获取的类加载器

    loadSpringFactories

    继续跟进源码,查看最底层的loadSpringFactories方法

    1. private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
    2. ...
    3. try {
    4. Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
    5. while (urls.hasMoreElements()) {
    6. URL url = urls.nextElement();
    7. UrlResource resource = new UrlResource(url);
    8. Properties properties = PropertiesLoaderUtils.loadProperties(resource);
    9. for (Map.Entry<?, ?> entry : properties.entrySet()) {
    10. String factoryTypeName = ((String) entry.getKey()).trim();
    11. String[] factoryImplementationNames =
    12. StringUtils.commaDelimitedListToStringArray((String) entry.getValue());
    13. for (String factoryImplementationName : factoryImplementationNames) {
    14. result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())
    15. .add(factoryImplementationName.trim());
    16. }
    17. }
    18. }
    19. }
    20. ...
    21. }

     可以看到,loadSpringFactories方法通过类加载器获取META-INF/spring.factories资源,我们项目中的类路径下的(当然包括三方jar包)所有META-INF/spring.factories都会被读取,并返回被自动装配的类

    META-INF/spring.factories

    spring-boot-autoconfigure模块是springboot的自动装配模块

    查看该模块下的spring.factories文件

    可以看到,该文件下已经帮我们配置了相当多的Configuration类,这也是springboot实现约定大于配置的关键,至此谜团解开 

  • 相关阅读:
    day05vue学习
    docker (网卡设置、namespace、网络互通)
    MyBatis-Plus 实战教程四 idea插件
    SwiftUI 状态管理系统指南
    校物联网智慧安全用电平台的设计和运用-安科瑞黄安南
    2023_Spark_实验六:Scala面向对象部分演示(二)(IDEA开发)
    rust 创建多线程web server
    MVCC解决的问题是什么
    基于订单流的日内盘口策略
    基本的SELECT语句——“MySQL数据库”
  • 原文地址:https://blog.csdn.net/m0_64944491/article/details/136419461