spring boot 的自动装配原理

  1. 什么是自动装配?

    • 在传统的Spring程序开发中,需要我们手动配置大量的bean,例如数据源,事务管理器,视图解析器等。这些配置过程繁琐而容易出错,加大了开发难度和成本。而Spring Boot的自动装配机制则能够自动完成这些配置过程,使得开发者可以更加专注于业务逻辑的实现。

    • Spring Boot的自动装配通过扫描应用程序的classpath和依赖关系,自动配置和装配Spring应用程序所需的各种组件,提高了开发效率、减少了出错的可能性,并提升了应用程序的可维护性和可扩展性。

  2. 自动装配原理

    • 几个重要的概念:

      • 自动装配启动过程:在Spring Boot启动过程中,会扫描应用程序的classpath以及依赖关系,根据条件注解的判断结果来决定是否需要进行自动配置。
      • 条件注解(Conditional Annotation):Spring Boot使用条件注解来确定是否需要进行自动配置。条件注解基于条件评估,根据一定的条件来判断是否需要进行自动配置。常见的条件注解包括@ConditionalOnClass、@ConditionalOnMissingBean、@ConditionalOnProperty等。
      • Spring Boot Starter依赖:Spring Boot提供了一系列的Starter依赖,每个Starter依赖都定义了一组常用的依赖库,例如spring-boot-starter-web、spring-boot-starter-data-jpa等。这些Starter依赖通过自动配置机制,将所需的组件进行自动装配。
      • 自动配置类(Auto-Configuration Class):每个Starter依赖都包含一个或多个自动配置类,这些自动配置类使用条件注解来判断是否需要进行自动配置。自动配置类通常包含@Configuration注解,其中定义了各种bean的创建和配置。
      • 自动配置的优先级:在多个自动配置类中,可能存在相同类型的bean的创建和配置。Spring Boot使用自动配置的优先级来决定哪个自动配置类的设置会生效。一般来说,后加载的配置类会覆盖前面的配置类。开发者也可以通过自定义配置来覆盖默认的自动配置。
      • 自定义配置:如果应用程序需要对自动配置进行修改或扩展,可以提供自己的配置类。这样可以通过编写自定义的bean来替换或扩展自动配置中的默认行为。
    • 总结:Spring Boot的自动装配通过条件注解、自动配置类和Starter依赖等机制,根据条件判断和优先级规则来自动配置和装配应用程序所需的组件。这种方式简化了配置过程,提高了开发效率,同时也保留了灵活性,允许开发者进行自定义配置。

    • 具体解释:

    • 在SpringBoot的启动类上的@SpringBootApplication注解,实现了自动装配,他是一个复合注解,点进去之后发现有以下注解:

    @SpringBootConfiguration	//springboot配置
    @EnableAutoConfiguration	//自动配置
    @ComponentScan(				//组件扫描
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    ), @Filter(
        type = FilterType.CUSTOM,
        classes = {AutoConfigurationExcludeFilter.class}
    )}
    )
    
    • 组件扫描@ComponentScan

      • spring中的注解 ,它对应XML配置中的元素

      • 作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义加载到IOC容器中

    • springboot配置@SpringBootConfiguration

      • 作用:SpringBoot的配置类,标注在类上,表示这是一个SpringBoot的配置类,点进去之后有一个注解 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件,再点进去有一个 @Component 注解,说明启动类本身是Spring中的一个组件,负责启动应用。
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Configuration
    public @interface SpringBootConfiguration {
        @AliasFor(
            annotation = Configuration.class
        )
        boolean proxyBeanMethods() default true;
    }
    
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Configuration {
        @AliasFor(
            annotation = Component.class
        )
        String value() default "";
    
        boolean proxyBeanMethods() default true;
    }
    
    • 最重要的是其中的@EnableAutoConfiguration:以前我们需要自己配置的东西,SpringBoot可以自动帮我们配置 ; @EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效,点进去
    @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: 自动配置包,点进去是@Import({AutoConfigurationPackages.Registrar.class})注解,Registrar.class作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器
    @Import({AutoConfigurationImportSelector.class}),给容器导入AutoConfigurationImportSelector.class组件,这个组件是自动配置导入选择器,其中有一个方法如下:

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).getCandidates();
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }
    

    这个方法调用了ImportCandiates的load方法,这句的下面有一句断言,我们根据断言里的提示内容找到META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports.,这就是自动配置根源所在。

  3. 总结:

    • SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
    • 将这些值作为自动配置类导入容器,自动配置类就生效,帮我们进行自动配置工作
    • 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中
    • 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件
    • 有了自动配置类,免去了手动编写配置注入功能组件等的工作
  4. 启动类主要做了以下四件事情:

    • 推断应用的类型是普通的项目还是Web项目

    • 查找并加载所有可用初始化器 , 设置到initializers属性中

    • 找出所有的应用程序监听器,设置到listeners属性中

    • 推断并设置main方法的定义类,找到运行的主类

posted @ 2024-05-15 20:24  Hanyta  阅读(76)  评论(0编辑  收藏  举报