美文网首页
Spring Boot 自动配置@SpringBootAppli

Spring Boot 自动配置@SpringBootAppli

作者: Tinyspot | 来源:发表于2022-11-26 22:12 被阅读0次

    1. @SpringBootApplication

    • @SpringBootApplication 组合注解
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(...)
    public @interface SpringBootApplication {}
    

    1.3 拆分示例

    将 SpringBoot 启动类拆分为两个独立的Java类

        @Configuration
        @EnableAutoConfiguration
        @Component Scan
        public class DemoConfiguration {
            @Bean
            public Controller controller() {
                return new Controller();
            }
        }
    
        public class DemoApplication {
            public static void main(String[] args) {
                SpringApplication.run(DemoConfiguration.class, args);
            }
        }
    

    2. @SpringBootConfiguration

    • 包含 @Configuration, 代表启动类就是一个配置类

    3. @ComponentScan

    • 扫描包

    4. @EnableAutoConfiguration

    • 实现自动装配
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {}
    

    4.1 @AutoConfigurationPackage

    • 自动配置包,指定默认的包规则
    @Import(AutoConfigurationPackages.Registrar.class)
    public @interface AutoConfigurationPackage {}
    

    利用 Registrar 给容器注入一系列组件

    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
      @Override
      public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
      register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
      }
    
      @Override
      public Set<Object> determineImports(AnnotationMetadata metadata) {
        return Collections.singleton(new PackageImports(metadata));
      }
    }
    

    4.2 AutoConfigurationImportSelector.class

    public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
            ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
        protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        // ...
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
      }
    }
    
    1. AutoConfigurationImportSelector.getAutoConfigurationEntry(annotationMetadata)
    2. AutoConfigurationImportSelector.getCandidateConfigurations(annotationMetadata, attributes)
    3. SpringFactoriesLoader.loadFactoryNames
    4. SpringFactoriesLoader.loadSpringFactories
    4.1 Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
    4.2 FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
    
    1. 利用 getAutoConfigurationEntry(annotationMetadata) 给容器中批量导入组件
    2. 调用 getCandidateConfigurations(annotationMetadata, attributes) 获取所有需要导入容器的配置类
    3. 利用工厂加载loadSpringFactories() 获取所有组件
    4. 从 META-INF/spring.factories 加载

    5. 按需开启自动配置项

    • 自动配置功能在 spring-boot-autoconfigure 包里
    • 按照条件装配规则(@Conditional) 按需配置

    分析类 org.springframework.boot.autoconfigure.aop.AopAutoConfiguration

    public class AopAutoConfiguration {
      @Configuration(proxyBeanMethods = false)
      @ConditionalOnClass(Advice.class)
      static class AspectJAutoProxyingConfiguration {}
      
      @Configuration(proxyBeanMethods = false)
      @ConditionalOnMissingClass("org.aspectj.weaver.Advice")
      @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
                matchIfMissing = true)
      static class ClassProxyingConfiguration {}
    }
    

    6. SpringFactoriesLoader 类

    • SpringBoot 项目启动时,SpringFactoriesLoader 类(在 spring-core.jar)
    public final class SpringFactoriesLoader {
        public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
        
        public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
            // ...
            for (String factoryImplementationName : factoryImplementationNames) {
                result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
            }
            AnnotationAwareOrderComparator.sort(result);
            return result;
        }
    }
    

    在 spring-boot-autoconfigure.jar 的 spring.factories 文件里配置了 WebMvcAutoConfiguration

    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
    

    查看 WebMvcAutoConfiguration 类,实际是由 DispatcherServletAutoConfiguration 类实现加载

    @AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
    public class WebMvcAutoConfiguration {}
    

    相关文章

      网友评论

          本文标题:Spring Boot 自动配置@SpringBootAppli

          本文链接:https://www.haomeiwen.com/subject/vjfhfdtx.html