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

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

文章目录

    • 5.1 引导加载自动配置类
      • 5.1.1 @SpringBootConfiguration
      • 5.2.2 @ComponentScan
      • 5.2.3 @EnableAutoConfiguration
    • 5.2 按需开启自动配置项
    • 5.3 修改默认配置
    • 5.4 总结
    • 5.5 最佳实践-SpringBoot应用如何编写
    • 5.6 常用开发技巧
      • 5.6.1 Lombok简化开发
      • 5.6.2 dev-tools
      • 5.6.3 Spring Initailizr

5.1 引导加载自动配置类

  • Spring Boot应用的启动类:

    @SpringBootApplication
    public class MainApplication {
        public static void main(String[] args) {
            SpringApplication.run(MainApplication.class, args);
        }
    }
    

    或者

    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(
        excludeFilters = {@Filter(
            type = FilterType.CUSTOM,
            classes = {TypeExcludeFilter.class}
        ), @Filter(
            type = FilterType.CUSTOM,
            classes = {AutoConfigurationExcludeFilter.class}
        )}
    )
    public @interface SpringBootApplication {    
    	...
    }
    

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 {};
}
  • @AutoConfigurationPackage:自动配置包,指定了默认的包规则。利用Registrar给容器中导入一系列组件。

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

    SpringBoot:(五)自动配置原理解析_第1张图片

5.2 按需开启自动配置项

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

    • 比如AopAutoConfiguration类:

      @Configuration(proxyBeanMethods = false)
      @ConditionalOnProperty(
          prefix = "spring.aop",
          name = {"auto"},
          havingValue = "true",
          matchIfMissing = true
      )
      public class AopAutoConfiguration {
          public AopAutoConfiguration() {
          }
          ...
      }
      

5.3 修改默认配置

  • DispatcherServletAutoConfiguration的内部类DispatcherServletConfiguration为例子:

    @Bean
    @ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
    @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
    public MultipartResolver multipartResolver(MultipartResolver resolver) {
    	return resolver;//给容器中加入了文件上传解析器;
    }
    
  • 给@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>
    
  • 示例

    @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;
        }
    }
    
  • 各个注解的作用:

    • @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>
    
  • 我的评价是:鸡肋!

5.6.3 Spring Initailizr

  • 基本使用:Spring Initailizr是创建Spring Boot工程向导
  • IDEA中,在创建项目时,菜单栏New -> Project -> Spring Initailizr,勾选需要的开发场景,Spring Initailizr会自动构建好项目。

你可能感兴趣的:(Java后端开发技术栈,spring,boot,spring,java)