Spring Boot 自动配置@SpringBootAppli

2022-11-26  本文已影响0人  Tinyspot

1. @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

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. 按需开启自动配置项

分析类 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 类

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 {}
上一篇下一篇

猜你喜欢

热点阅读