• SpringBoot:(五)自动配置原理解析


    笔记来源:【尚硅谷】SpringBoot2零基础入门教程(spring boot2干货满满)

    5.1 引导加载自动配置类

    • Spring Boot应用的启动类:

      @SpringBootApplication
      public class MainApplication {
          public static void main(String[] args) {
              SpringApplication.run(MainApplication.class, args);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      或者

      @SpringBootConfiguration
      @EnableAutoConfiguration
      @ComponentScan(
          excludeFilters = {@Filter(
              type = FilterType.CUSTOM,
              classes = {TypeExcludeFilter.class}
          ), @Filter(
              type = FilterType.CUSTOM,
              classes = {AutoConfigurationExcludeFilter.class}
          )}
      )
      public @interface SpringBootApplication {    
      	...
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

    5.1.1 @SpringBootConfiguration

    • @SpringBootConfiguration:代表当前类是一个配置类

    5.2.2 @ComponentScan

    • @ComponentScan:指定扫描的路径

    5.2.3 @EnableAutoConfiguration

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
        String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    
        Class<?>[] exclude() default {};
    
        String[] excludeName() default {};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • @AutoConfigurationPackage:自动配置包,指定了默认的包规则。利用Registrar给容器中导入一系列组件。

      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      @Inherited
      @Import(AutoConfigurationPackages.Registrar.class)// 利用Registrar给容器中导入一系列组件
      public @interface AutoConfigurationPackage {
          String[] basePackages() default {};
      
          Class<?>[] basePackageClasses() default {};
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • @Import(AutoConfigurationImportSelector.class):默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件,获取到所有需要导入到容器中的配置类xxxxAutoConfiguration。(似乎新版本的Spring Boot把所有类的META-INF/spring.factories合起来放在一起了,一共一百多个)。

      image-20221106035531329

    5.2 按需开启自动配置项

    • 虽然一共加载了一百多个xxxxAutoConfiguration配置类,但实际上,这些配置类中都包含了条件装配注解(@Conditional),按照条件装配规则,最终会按需配置

      • 比如AopAutoConfiguration类:

        @Configuration(proxyBeanMethods = false)
        @ConditionalOnProperty(
            prefix = "spring.aop",
            name = {"auto"},
            havingValue = "true",
            matchIfMissing = true
        )
        public class AopAutoConfiguration {
            public AopAutoConfiguration() {
            }
            ...
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12

    5.3 修改默认配置

    • DispatcherServletAutoConfiguration的内部类DispatcherServletConfiguration为例子:

      @Bean
      @ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
      @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
      public MultipartResolver multipartResolver(MultipartResolver resolver) {
      	return resolver;//给容器中加入了文件上传解析器;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。目的是防止有些用户配置的文件上传解析器不符合规范。

    • SpringBoot默认会在底层配好所有的组件,但是如果用户自己配置了以用户的优先

    5.4 总结

    • SpringBoot先加载所有的自动配置类xxxxAutoConfiguration
    • 每个自动配置类按照条件进行生效
    • 每个自动配置类都会从xxxxProperties类里面读取配置,xxxProperties和配置文件application.properties进行了绑定。
    • 生效的配置类就会给容器中装配很多组件,只要容器中有这些组件,相当于这些功能就有了
    • 如果程序员需要定制化配置,则可以:
      • 直接自己在配置类中@Bean替换底层的组件
      • 修改application.properties对于某个自动配置类的相关配置

    xxxxxAutoConfiguration ----> xxxxProperties ----> application.properties

    5.5 最佳实践-SpringBoot应用如何编写

    • 引入场景依赖
    • 查看自动配置了的详细信息
      • 可以在配置文件中debug=true开启自动配置报告。
        • Negative(不生效)
        • Positive(生效)
    • 是否需要修改配置
      • 参照文档修改配置项,官方文档
      • 自定义组件替换底层组件
        • @Bean、@Component…
      • 自定义器 XXXXXCustomizer;

    5.6 常用开发技巧

    5.6.1 Lombok简化开发

    • 基本使用:Lombok用标签方式代替构造器、getter/setter、toString()等鸡肋代码

    • spring boot已经管理Lombok,并未集成了Lombok插件。只需要引入依赖即可使用:

      <dependency>
          <groupId>org.projectlombokgroupId>
          <artifactId>lombokartifactId>
      dependency>
      
      • 1
      • 2
      • 3
      • 4
    • 示例

      @Data
      @ToString
      @NoArgsConstructor
      @AllArgsConstructor
      @EqualsAndHashCode
      @Component
      public class User {
          private String name;
          private int age;
          private Pet pet;
      
          public User(String name, int age) {
              this.name = name;
              this.age = age;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 各个注解的作用:

      • @Data:自动生成get、set方法
      • @ToString:自动生成toString方法
      • @NoArgsConstructor:自动生成无参构造器
      • @AllArgsConstructor:自动生成包含所有成员变量的有参构造器
      • @EqualsAndHashCode:自动生成equal和hashcode方法
    • 简化日志开发:使用@Slf4j注解

    5.6.2 dev-tools

    • 基本使用:可以使用ctrl+F9来重新启动项目

    • 添加依赖:

      <dependencies>
          <dependency>
              <groupId>org.springframework.bootgroupId>
              <artifactId>spring-boot-devtoolsartifactId>
              <optional>trueoptional>
          dependency>
      dependencies>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 我的评价是:鸡肋!

    5.6.3 Spring Initailizr

    • 基本使用:Spring Initailizr是创建Spring Boot工程向导
    • IDEA中,在创建项目时,菜单栏New -> Project -> Spring Initailizr,勾选需要的开发场景,Spring Initailizr会自动构建好项目。
  • 相关阅读:
    CCPC 2021威海 - G. Shinyruo and KFC(组合数,小技巧)
    什么是http无状态?怎么解决的?
    C++中vector<string>使用C字符时的小坑与分析
    part_two:多媒体软硬件平台技术
    2022年深圳市福田区支持先进制造业发展若干措施
    imitation learning
    谈谈JDK 漏洞 6260652
    docker命令,免sudo
    java毕业设计奇妙店铺电子商务网站源码+lw文档+mybatis+系统+mysql数据库+调试
    实战|轻松用 Python 开发一个简单有趣的聊天小程序
  • 原文地址:https://blog.csdn.net/sd_960614/article/details/127711912