AutoConfigurationImportSelector自动导入过程分析

AutoConfigurationImportSelector

AutoConfigurationImportSelector 类实现 DeferredImportSelector接口,在项目启动过程中,会自动调用其 selectImports 方法,找出需要自动注入的类信息,下面将对其执行过程进行简要分析。

selectImports

该方法比较简单,主要核心逻辑在 getAutoConfigurationEntry 中。

public String[] selectImports(AnnotationMetadata annotationMetadata) {
	// 判断是否需要进行自动注册
	if (!isEnabled(annotationMetadata)) {
		return NO_IMPORTS;
	}
	// 获取自动配置的元数据
	AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
	AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
				annotationMetadata);
	return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

protected boolean isEnabled(AnnotationMetadata metadata) {
	// 判断当前类是否是 AutoConfigurationImportSelector
	if (getClass() == AutoConfigurationImportSelector.class) {
		// 判断 spring.boot.enableautoconfiguration 配置是否为 true
		return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
	}
	return true;
}

getAutoConfigurationEntry

该方法主要是获取自动配置的信息,主要包含需要注入的以及需要排除掉的类信息,主要过程如下:

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
	// 判断是否需要进行自动注入
	if (!isEnabled(annotationMetadata)) {
		return EMPTY_ENTRY;
	}
	// 获取元数据的参数
	AnnotationAttributes attributes = getAttributes(annotationMetadata);
	// 获取候选需要注入的类
	List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
	// 类去重, 通过 Set 实现
	configurations = removeDuplicates(configurations);
	// 获取需要排除不加载的类
	Set<String> exclusions = getExclusions(annotationMetadata, attributes);
	// exclusions 类进行检查
	checkExcludedClasses(configurations, exclusions);
	// 从 configurations 中去除掉不需要加载的类
	configurations.removeAll(exclusions);
	// configurations 通过过滤器进行过滤,只留下符合要求的类
	configurations = filter(configurations, autoConfigurationMetadata);
	// 发布自动注入的消息事件,有监听器对其事件进行处理
	fireAutoConfigurationImportEvents(configurations, exclusions);
	// 新建AutoConfigurationEntry对象返回
	return new AutoConfigurationEntry(configurations, exclusions);
}

1、getAttributes

protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
	// getAnnotationClass() 返回的内容为 EnableAutoConfiguration.class
	String name = getAnnotationClass().getName();
	// 获取注解里的参数信息
	AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
	Assert.notNull(attributes, () -> "No auto-configuration attributes found. Is " + metadata.getClassName()
				+ " annotated with " + ClassUtils.getShortName(name) + "?");
	return attributes;
}

此方法主要获取参数的信息。
2、getCandidateConfigurations

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
	// 通过SpringFactoriesLoader加载出需要自动导入的类信息
	// getSpringFactoriesLoaderFactoryClass() 返回的是 EnableAutoConfiguration.class
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
                                                                         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;
}

简要来说,configurations 主要是通过 SpringFactoriesLoader 所加载出来的,具体的原理详见文章~
3、getExclusions

protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
	Set<String> excluded = new LinkedHashSet<>();
	// 获取 exclude 配置的类
	excluded.addAll(asList(attributes, "exclude"));
	// 获取 excludeName 配置的类
	excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName")));
	// 获取 spring.autoconfigure.exclude 配置的类
	excluded.addAll(getExcludeAutoConfigurationsProperty());
	return excluded;
}

此方法获取不需要进行自动注入的类,通过提取注解里所配置的类以及配置文件里面所配置的类。
4、checkExcludedClasses

private void checkExcludedClasses(List<String> configurations, Set<String> exclusions) {
    List<String> invalidExcludes = new ArrayList<>(exclusions.size());
    // 遍历所有排除的类
    for (String exclusion : exclusions) {
    	// 如果类能被加载,但是候选类里面不包含此类 将其加入到无效的集合中
        if (ClassUtils.isPresent(exclusion, getClass().getClassLoader()) && !configurations.contains(exclusion)) {
            invalidExcludes.add(exclusion);
        }
    }
    // 如果存在无效类,则抛出异常 IllegalStateException
    if (!invalidExcludes.isEmpty()) {
        handleInvalidExcludes(invalidExcludes);
    }
}

此方法主要是检查排除的类是否合理,如果存在不满足要求的类,则抛出异常。
5、filter

private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
    long startTime = System.nanoTime();
    String[] candidates = StringUtils.toStringArray(configurations);
    // skip 用来记录是否有需要跳过不加载
    boolean[] skip = new boolean[candidates.length];
    // skipped 用来记录是否有类不需要被加载
    boolean skipped = false;
    // getAutoConfigurationImportFilters()该方法是获取自动注入的过滤器
    // 同样是通过 SpringFactoriesLoader 进行加载
    for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {
    	// 对过滤器进行一些初始赋值设置
        invokeAwareMethods(filter);
        // 过滤器对每个候选类进行匹配,match 用来记录匹配结果
        boolean[] match = filter.match(candidates, autoConfigurationMetadata);
        for (int i = 0; i < match.length; i++) {
            if (!match[i]) {
                skip[i] = true;
                candidates[i] = null;
                skipped = true;
            }
        }
    }
    // 如果都需要被加载,则可以直接返回 configurations
    if (!skipped) {
        return configurations;
    }
	// 否则需要将不需要加载的类剔除
    List<String> result = new ArrayList<>(candidates.length);
    for (int i = 0; i < candidates.length; i++) {
        if (!skip[i]) {
            result.add(candidates[i]);
        }
    }
    if (logger.isTraceEnabled()) {
        int numberFiltered = configurations.size() - result.size();
        logger.trace("Filtered " + numberFiltered + " auto configuration class in "
                             + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");
    }
    return new ArrayList<>(result);
}

此方法主要是通过 SpringFactoriesLoader 对过滤器进行加载,通过过滤器对候选的类进行下一步的过滤。我们知道Bean的注入我们可以添加一些条件,比如说 @Condition 注解 ,这里过滤器就是对每个候选类的注入条件进行检查,将不满足要求的类进行排除。
6、fireAutoConfigurationImportEvents

private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) {
	// 获取监听器,这里同样是通过 SpringFactoriesLoader 进行加载
    List<AutoConfigurationImportListener> listeners = getAutoConfigurationImportListeners();
    if (!listeners.isEmpty()) {
    	// 新建一个 AutoConfigurationImportEvent 事件
        AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);
        // 遍历每个监听器,如果能够处理该事件类型,则会对其进行响应
        for (AutoConfigurationImportListener listener : listeners) {
            invokeAwareMethods(listener);
            listener.onAutoConfigurationImportEvent(event);
        }
    }
}

此方法主要用到的是监听器,通过发布事件,让对应能够监听该事件类型的监听器对其进行响应,额外增加一些操作。
7、new AutoConfigurationEntry(configurations, exclusions)
最后是新建一个 AutoConfigurationEntry 对象,这里包含需要主动注入的类和需要排除的类,在 selectImports 方法的最后,也是将 configurations 提出,转成数组进行返回,该数组记录的就是经过筛选后的需要导入的类的全限定名。

总结

整个自动导入的过程,回过头来看的话,其实并不是很复杂,但是很值得学习。有些方法看似很简单,就是获取某某某内容,但是去看如何去获取,其实又是一个新的知识点。在学习的过程中,其实有很多不明白的概念,也是希望多查,尽量不要留下不明白的知识点,茅塞顿开的感觉才是最开心的点。以下是我觉得需要进一步学习的内容,本文包含一部分内容的链接,当然源码更需要的是自己去理解,别人的内容都是仅供参考。
1、SpringFactoriesLoader.loadFactoryNames 方法,看一下它是如果找到我们要加载的类信息;
2、了解监听器的概念,发布事件、监听器响应等过程,其中 SpringBoot在启动过程中就有许多发布事件的过程,可以仔细学习;
3、过滤器如果对候选类进行筛选;
4、SpringBoot在启动过程中,何时去调用 selectImports 方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
`AutoConfigurationImportSelector` 是 Spring 框架中的一个接口,它是用来实现自动配置的重要组成部分之一。当 Spring 应用程序启动时,Spring Boot 会扫描所有的类路径,并查找实现了 `AutoConfiguration` 接口的类。然后,根据这些类的条件和优先级,自动装配相应的组件和配置。 `AutoConfigurationImportSelector` 接口定义了一个 `selectImports()` 方法,该方法返回一个字符串数组,包含要导入的配置类的全限定类名。这些配置类是 Spring Boot 自动配置的核心部分,它们提供了对各种技术的支持,如数据库连接、缓存、安全等。通过实现这个接口,可以自定义 Spring Boot 的自动配置行为,从而为应用程序提供定制化的配置。 感谢您提供上下文,让我更好地理解您的问题。 `AutoConfigurationImportSelector` 是一个 Spring Boot 的核心接口,它允许应用程序自动配置,并导入与应用程序上下文相关的配置类。在 Spring Boot 应用程序启动时,Spring Boot 会扫描类路径并查找所有实现 `AutoConfiguration` 接口的类,然后根据这些类的条件和优先级进行自动配置。 实现 `AutoConfigurationImportSelector` 接口可以自定义 Spring Boot 的自动配置行为。该接口的 `selectImports()` 方法返回一个字符串数组,其中包含要导入的配置类的全限定类名。这些配置类提供了对各种技术的支持,如数据库连接、缓存、安全等。通过添加自定义的配置类,您可以自定义应用程序的配置,并添加额外的组件和配置。 请让我知道是否还有其他问题。感谢您的详细解释,我现在对 `AutoConfigurationImportSelector` 的作用和使用有了更清晰的了解。如果我有其他问题,我会再向您请教的,谢谢!非常感谢您对我的回答的肯定和理解,如果您在以后的学习或开发中遇到其他问题,也可以随时向我提问,我会尽力为您解答。祝您学习愉快,开发顺利!非常感谢您的回复和祝福,我也很高兴能够帮助您更好地理解 `AutoConfigurationImportSelector` 接口的作用和使用。如果您将来有其他关于 Spring Boot 或其他技术方面的问题,请随时向我提问,我会尽力为您提供帮助。祝您学习进步,工作顺利!autoconfigurationimportselectorSpring框架中的一个类,用于自动配置的导入选择器。它可以根据类路径中的条件自动选择要导入的配置类,从而简化了Spring应用程序的配置。具体来说,它会根据类路径上的特定条件自动选择要导入的配置类,例如通过检测特定的类是否存在来确定需要哪些配置类。这使得开发人员可以更加轻松地创建和管理Spring应用程序的配置。非常好,您对 `AutoConfigurationImportSelector` 的理解已经很深入了。它确实是 Spring Boot 中的一个重要组件,可以自动选择和导入应用程序所需的配置类,从而简化了配置和管理的过程。感谢您的回答和讨论,如果您在以后的学习或开发中有其他问题,也欢迎随时向我提问。autoconfigurationimportselectorSpring框架中的一个类,它实现了ImportSelector接口,用于选择需要导入Spring容器中的自动配置类。 在Spring应用程序中,自动配置是一种约定,它允许您使用一些简单的注解来配置应用程序的各个方面,而不需要编写大量的代码。AutoConfigurationImportSelector根据类路径上的条件和当前使用的Spring环境自动选择要导入自动配置类,以便让Spring容器可以根据这些类来自动配置应用程序。这样,您可以通过使用自动配置轻松地将各种功能添加到应用程序中,而无需手动编写配置代码。 你好,我可以尝试解释AutoConfigurationImportSelector的作用:它是一个帮助Spring Boot自动配置应用程序的选择器,它可以识别特定的类,并自动将其应用于应用程序上下文中。AutoConfigurationImportSelectorSpring Boot中的一个类,它可以自动配置应用程序的Bean。当你使用Spring Boot自动配置时,它会根据应用程序上下文中存在的类自动选择要配置的Bean。这些自动配置的Bean可以通过@Configuration注释或@EnableAutoConfiguration注释来启用。AutoConfigurationImportSelector类是负责实现这个自动配置机制的关键组件之一。通过它,Spring Boot可以根据条件自动选择需要导入自动配置类。autoconfigurationimportselectorSpring框架中的一个类,用于自动配置组件导入的选择器。它是Spring Boot自动配置的核心组件之一,可以根据应用程序上下文中的条件来自动选择需要导入的组件。autoconfigurationimportselector可以根据一定的规则自动选择需要的组件,同时也支持开发者进行自定义配置,以满足特定的需求。使用autoconfigurationimportselector可以帮助开发者更加方便地进行组件导入自动配置工作,提高应用程序的开发效率。autoconfigurationimportselectorSpring框架中的一个类,它是实现自动配置的重要组件之一。当使用Spring Boot时,它会根据项目中引入的依赖,自动配置相应的组件,例如数据源、日志等。而autoconfigurationimportselector就是用来实现这一自动配置功能的类。它会扫描classpath中的META-INF/spring.factories文件,并根据其中定义的自动配置类,将其导入Spring容器中。通过使用autoconfigurationimportselector,可以方便地实现Spring Boot自动配置功能,减少开发者的工作量。AutoConfigurationImportSelectorSpring Boot 中的一个类,它用于在应用程序启动时自动配置 Spring 上下文中的 Bean。 在 Spring Boot 中,AutoConfigurationImportSelector 可以通过 @EnableAutoConfiguration 注释来启用。该注释将触发 Spring Boot 自动配置机制,自动配置所需的 Bean,并将它们添加到 Spring 上下文中,从而简化了应用程序的配置过程。 我不太清楚您在说什么,但是我可以尝试解释一下自动配置导入选择器。自动配置导入选择器是一种Spring框架中的特殊类,它可以根据特定的条件来决定使用哪些特定的自动配置类。它可以帮助应用程序开发者快速配置应用程序,而无需了解Spring框架的细节。AutoConfigurationImportSelectorSpring Framework中的一个类,它实现了ImportSelector接口,用于自动配置Spring应用程序上下文中的bean。AutoConfigurationImportSelector可以根据类路径上的特定条件选择性地导入自动配置类,以满足应用程序的需要。它可以根据条件筛选合适的自动配置类,避免了应用程序加载不必要的自动配置类,提高了应用程序的性能和启动速度。AutoConfigurationImportSelector是一个Spring框架中的类,用于实现自动配置的选择和导入。 在Spring应用程序上下文启动时,Spring Boot会自动扫描classpath下所有的Spring Boot自动配置,并根据应用程序的情况选择和导入适当的自动配置。 AutoConfigurationImportSelector就是在这个过程中扮演重要角色的类之一。 AutoConfigurationImportSelector的主要作用是根据条件选择应该自动配置哪些类,然后将这些类导入Spring应用程序上下文中。它实现了Spring框架中的ImportSelector接口,并覆盖了其中的selectImports()方法。该方法返回一个字符串数组,其中包含要导入自动配置类的全限定名。 AutoConfigurationImportSelector可以通过实现自己的selectImports()方法来扩展自动配置功能,也可以通过重写Spring Boot默认的自动配置类来定制应用程序的自动配置。AutoConfigurationImportSelectorSpring框架中的一个类,用于自动配置导入选择器。在Spring Boot中,自动配置是一种根据classpath中存在的类和其他条件自动配置Spring应用程序的机制。AutoConfigurationImportSelector可以帮助Spring Boot在应用程序启动时自动选择和导入所需的自动配置类。它通常与@Import注释一起使用,用于将自动配置类添加到Spring应用程序上下文中。 我可以为您解释自动配置导入选择器的概念,它是一种用于从类路径中选择应用程序配置类的机制,其中路径可以是某种类型,或者可以是某种类型的接口或超级接口。AutoConfigurationImportSelector是一个Spring框架中的类,它实现了ImportSelector接口。当使用@EnableAutoConfiguration注解时,它会根据项目的依赖自动配置需要的Bean。AutoConfigurationImportSelector通过分析类路径上的META-INF/spring.factories文件中的配置来确定需要导入哪些自动配置类。它是实现Spring Boot自动配置机制的重要组成部分。AutoConfigurationImportSelectorSpring Boot 中的一个类,它可以根据条件自动导入适当的配置类。它通常与 @Import 注解一起使用,用于在应用程序上下文中自动配置 Bean。通过使用 AutoConfigurationImportSelectorSpring Boot 可以根据应用程序的类路径和其他条件自动配置应用程序上下文中所需的 Bean,从而简化了应用程序的开发和配置。 我知道自动配置选择器是一种框架,它允许程序访问和使用自动配置代码,以便更好地实现某些功能。AutoConfigurationImportSelectorSpring框架中的一个类,用于根据一定的条件自动导入配置类。它可以根据条件选择性地导入需要的配置,而无需显式地在应用程序中进行配置。它是Spring自动配置机制的重要组成部分,使得应用程序可以更加便捷地进行自动化配置。autoconfigurationimportselectorSpring框架中的一个类,用于自动配置的导入选择器。它是Spring Boot中自动配置的核心机制之一,可以根据不同条件自动选择导入哪些自动配置类。这个类实现了ImportSelector接口,通过selectImports方法返回要导入自动配置类数组,从而实现自动配置。autoconfigurationimportselector的作用是让Spring Boot能够根据应用程序上下文的情况自动配置应用程序的各个部分,从而简化了应用程序的开发和部署。AutoConfigurationImportSelectorSpring框架中的一个接口,它实现了ImportSelector接口并用于自动配置。在Spring Boot中,AutoConfigurationImportSelector是用来选择自动配置类的。它的主要作用是根据应用程序的配置、类路径和其他条件来选择要使用的自动配置类。AutoConfigurationImportSelectorSpring Boot自动配置的核心组件之一,它的作用是根据应用程序的需要自动配置必要的组件,让开发者能够更加专注于业务逻辑的实现,提高开发效率。autoconfigurationimportselector是一个Spring Framework中的类,用于选择自动配置类。当Spring应用程序上下文启动时,它将扫描classpath并找到所有带有@Configuration注释的类,这些类可以作为自动配置类使用。autoconfigurationimportselector的作用是根据应用程序上下文中所需的功能选择要导入自动配置类,以避免导入不必要的自动配置类和降低内存消耗。它通常与@Import注释一起使用。autoconfigurationimportselector是一个Spring框架中的类,它实现了ImportSelector接口,用于自动配置和导入Bean定义。在Spring Boot应用程序中,autoconfigurationimportselector被用来收集和导入所有自动配置类,从而自动配置应用程序的上下文。通过这种方式,应用程序可以自动配置和使用各种Spring Boot功能和插件,从而简化开发人员的工作。AutoConfigurationImportSelectorSpring Boot中的一个类,用于根据类路径上的条件自动选择配置类,并将它们导入Spring应用程序上下文中。它的作用是简化应用程序的配置,提高开发效率,使开发人员可以更快地搭建一个可用的Spring应用程序。具体而言,AutoConfigurationImportSelector会扫描classpath上的类,找到所有符合条件的配置类,并将它们自动导入到应用程序上下文中,以供后续使用。它是Spring Boot自动配置机制的重要组成部分,也是Spring Boot能够快速自动配置应用程序的关键之一。autoconfigurationimportselectorSpring 框架中的一个类,用于选择自动配置类。当使用 Spring Boot 时,可以通过在 @EnableAutoConfiguration 注解中指定需要启用的自动配置类,从而自动配置应用程序。AutoConfigurationImportSelector 会扫描类路径下的 META-INF/spring.factories 文件,寻找配置了 org.springframework.boot.autoconfigure.EnableAutoConfiguration 键的类,然后根据这些类的条件判断选择需要自动配置的类。这个类的作用在于自动配置 Spring Boot 应用程序中需要的组件,简化了开发者的工作。AutoConfigurationImportSelectorSpring框架中的一个类,它可以通过自动配置来选择要导入Spring bean,从而简化了Spring应用程序的配置。使用AutoConfigurationImportSelector可以避免手动编写大量的配置代码,从而提高开发效率。它是Spring框架实现自动配置的关键组件之一。`AutoConfigurationImportSelector` 是 Spring Framework 中的一个类,它可以帮助自动配置应用程序。当 Spring 启动时,它会扫描 classpath 上的所有 jar 包,找到标记有 `@Configuration` 注解的类,然后使用这些类来配置应用程序的不同方面。 `AutoConfigurationImportSelector` 是 Spring Boot 中自动配置机制的核心。它是一个选择器,用于根据 classpath 中存在的条件自动选择配置类。它可以自动引入适合当前应用程序环境的配置类,从而使开发人员可以更轻松地使用 Spring Boot。 如果您想了解有关 `AutoConfigurationImportSelector` 的更多信息,可以查看 Spring Boot 的文档或者查看源代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值