SPRINGBOOT02_自动配置原理入门、Lombok、dev-tools、快速初始化boot项目(二)

简介: SPRINGBOOT02_自动配置原理入门、Lombok、dev-tools、快速初始化boot项目(二)

③. @ComponentScan



  • 扫描标明了@SpringBootApplication的类或及其子包进行一个扫描


@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {


④. @EnableAutoConfiguration


  • ①. 主要的代码如下


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {


②. @AutoConfigurationPackage:给容器中导入一个组件,利用Registrar给容器导入一系列组件,将指定的一个包下的所有组件导入进来(MainApplication所在的包下)


微信图片_20220109212307.png


③. @Import(AutoConfigurationImportSelector.class)


(1). 利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件


(2). 调用List configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类


(3). 利用工厂加载 Map<String, List> loadSpringFactories(@Nullable ClassLoader classLoader):得到所有的组件


(4). 从META-INF/spring.factories位置来加载一个文件。


默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件


spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories


并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean


   public String[] selectImports(AnnotationMetadata annotationMetadata) {
       if (!this.isEnabled(annotationMetadata)) {
           return NO_IMPORTS;
       } else {
           //(1). 利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
           AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry =
           this.getAutoConfigurationEntry(annotationMetadata);
           return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
       }
   }
   protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
      if (!this.isEnabled(annotationMetadata)) {
          return EMPTY_ENTRY;
      } else {
          AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
          //(2). 调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)
          //获取到所有需要导入到容器中的配置类
          List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
          configurations = this.removeDuplicates(configurations);
          Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
          this.checkExcludedClasses(configurations, exclusions);
          configurations.removeAll(exclusions);
          configurations = this.getConfigurationClassFilter().filter(configurations);
          this.fireAutoConfigurationImportEvents(configurations, exclusions);
          return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
      }
  }
   protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
      List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
      Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
      return configurations;
  }
  //(3). 利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader 
  //classLoader)得到所有的组件
  public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
      String factoryTypeName = factoryType.getName();
      return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
  }
  private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
     MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
      if (result != null) {
          return result;
      } else {
          try {
          //(4). 从META-INF/spring.factories位置来加载一个文件
          Enumeration<URL> urls = classLoader != null ? classLoader.getResources
          ("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
          LinkedMultiValueMap result = new LinkedMultiValueMap();


相关文章
|
29天前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
29 0
|
1月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
50 0
|
1天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
28 14
|
23天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
41 1
SpringBoot入门(7)- 配置热部署devtools工具
|
23天前
|
Java 容器
springboot自动配置原理
启动类@SpringbootApplication注解下,有三个关键注解 (1)@springbootConfiguration:表示启动类是一个自动配置类 (2)@CompontScan:扫描启动类所在包外的组件到容器中 (3)@EnableConfigutarion:最关键的一个注解,他拥有两个子注解,其中@AutoConfigurationpackageu会将启动类所在包下的所有组件到容器中,@Import会导入一个自动配置文件选择器,他会去加载META_INF目录下的spring.factories文件,这个文件中存放很大自动配置类的全类名,这些类会根据元注解的装配条件生效,生效
|
25天前
|
存储 前端开发 JavaScript
springboot中路径默认配置与重定向/转发所存在的域对象
Spring Boot 提供了简便的路径默认配置和强大的重定向/转发机制,通过合理使用这些功能,可以实现灵活的请求处理和数据传递。理解并掌握不同域对象的生命周期和使用场景,是构建高效、健壮 Web 应用的关键。通过上述详细介绍和示例,相信读者能够更好地应用这些知识,优化自己的 Spring Boot 应用。
26 3
|
1月前
|
Java 数据库连接 数据库
springboot启动配置文件-bootstrap.yml常用基本配置
以上是一些常用的基本配置项,在实际应用中可能会根据需求有所变化。通过合理配置 `bootstrap.yml`文件,可以确保应用程序在启动阶段加载正确的配置,并顺利启动运行。
95 2
|
26天前
|
JavaScript 前端开发 Java
SpringBoot项目的html页面使用axios进行get post请求
SpringBoot项目的html页面使用axios进行get post请求
36 0
|
7月前
|
Java
SpringBoot项目集成Lombok
SpringBoot项目集成Lombok
68 1
|
Java Maven
Springboot 集成 Lombok
Springboot 集成 Lombok
96 0