引导加载自动配置类

总注解@SpringBootApplication

  1. @SpringBootConfiguration
  2. @EnableAutoConfiguration
  3. @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
  4. public @interface SpringBootApplication
  1. @SpringBootConfiguration,本质上就是@Configuration
  2. @ComponentScan,指定包扫描路径。
  3. @EnableAutoConfiguration部分源码如下:
    1. @AutoConfigurationPackage // 自动注册@SpringBootApplication类所在包的bean
    2. @Import(AutoConfigurationImportSelector.class) // 自动导入所有符合自动配置条件的bean并加载到容器
    3. public @interface EnableAutoConfiguration
    (1)注解@AutoConfigurationPackage给IOC容器中导入了一个Registrar组件:
    1. @Import(AutoConfigurationPackages.Registrar.class)
    2. public @interface AutoConfigurationPackage
    Registrar实现了ImportBeanDefinitionRegistrar接口与,目的就是向IOC容器了批量注册@SpringBootApplication标注类所在包下的所有组件。
    1. static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    2. @Override // 批量注册组件
    3. public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
    4. // new PackageImport(metadata).getPackageName()
    5. // => @SpringBootApplication标注类所在的包
    6. register(registry, new PackageImport(metadata).getPackageName());
    7. // 批量注册这个包下的组件
    8. }
    9. }
    (2)@Import(AutoConfigurationImportSelector.class)通过@Import注解向IOC容器中导入自动配置选择器组件。 ```java // [AutoConfigurationImportSelector]

// 1. 获取所有自动配置 selectImports() => getAutoConfigurationEntry()

// 2. 获取所有需要导入到容器中配置类 getAutoConfigurationEntry() => getCandidateConfigurations()

// 3. 获取配置类后,移除重复,排除一些,过滤一些,检查一下

// [SpringFactoriesLoader]

// 4. 使用SpringFactoriesLoader加载 getCandidateConfigurations() => SpringFactoriesLoader.loadFactoryNames()

// 5. 从META-INF/spring.factories位置加载文件,默认扫描当前系统里面所有META-INF/spring.factories loadFactoryNames() => loadSpringFactories()

Enumeration urls = classLoader != null ? classLoader.getResources(“META-INF/spring.factories”) : ClassLoader.getSystemResources(“META-INF/spring.factories”)

// 核心:所有spring-boot-autoconfigure包下的META-INF/spring.factories文件,所有关于org.springframework.boot.autoconfigure的配置项

  1. 用一张图总结一下:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/493248/1641956307051-b982c356-96af-497e-ac0a-2387d86364fb.png#clientId=uca1b03bf-bafb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=580&id=ucb7f4611&margin=%5Bobject%20Object%5D&name=image.png&originHeight=580&originWidth=1440&originalType=binary&ratio=1&rotation=0&showTitle=false&size=102060&status=done&style=shadow&taskId=u1a86891c-3d20-40a2-ae21-946944b54db&title=&width=1440)
  2. <a name="EWXcK"></a>
  3. ## 按需开启自动配置项
  4. 虽然spring.factories的自动配置项默认全部加载,但是最终会按需配置。<br />拿`AopAutoConfiguration`的内部类举例,条件装配:
  5. - `@ConditionalOnClass`:必须导入相关依赖才能生效
  6. - `@ConditionalOnProperty`:必须配置文件中配置才能生效
  7. ```java
  8. @Configuration(proxyBeanMethods = false)
  9. @ConditionalOnClass(Advice.class)
  10. static class AspectJAutoProxyingConfiguration {
  11. @Configuration(proxyBeanMethods = false)
  12. @EnableAspectJAutoProxy(proxyTargetClass = false)
  13. @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
  14. static class JdkDynamicAutoProxyConfiguration { }
  15. @Configuration(proxyBeanMethods = false)
  16. @EnableAspectJAutoProxy(proxyTargetClass = true)
  17. @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
  18. static class CglibAutoProxyConfiguration { }
  19. @Configuration(proxyBeanMethods = false)
  20. @ConditionalOnMissingClass("org.aspectj.weaver.Advice") // 缺失这个类时生效
  21. @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true) // 默认开启AOP
  22. static class ClassProxyingConfiguration {
  23. ClassProxyingConfiguration(BeanFactory beanFactory) {
  24. if (beanFactory instanceof BeanDefinitionRegistry) {
  25. BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  26. AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
  27. AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
  28. }
  29. }
  30. }
  31. }