我是靠谱客的博主 时尚睫毛膏,最近开发中收集的这篇文章主要介绍spring @Import介绍文档翻译何时解析@Import,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文档翻译

指示要导入的一个或多个组件类——通常是@Configuration类。
提供与 Spring XML 中<import/>元素等效的功能。允许导入@Configuration类、 ImportSelector和ImportBeanDefinitionRegistrar实现,以及常规组件类(从 4.2 开始;类似于AnnotationConfigApplicationContext.register )

何时解析@Import

答:处理配置类时。具体代码分析如下:
ConfigurationClassParser#processConfigurationClass会调用
ConfigurationClassParser#doProcessConfigurationClass方法
, 在doProcessConfigurationClass中如下代码处理:(这一块属于ConfigurationClassPostProcessor相关的,这里不做介绍,简单可理解为扫描出的bean都会经过此处代码处理)


// Process any @Import annotations
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

getImports就是递归查找sourceClass上的@Import注解的值,就不展开看了,只看处理方法processImports。

processImports 处理@Import


for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
  • 候选类是一个ImportSelector,委托给ImportSelector以确定导入(导入其它bean)
  • 候选类是一个ImportBeanDefinitionRegistrar,委托给ImportBeanDefinitionRegistrar注册其他bean定义
  • 候选类不是ImportSelector或ImportBeanDefinitionRegistrar,将其作为@Configuration类处理。

ImportSelector处理

这里分为两种情况做了处理。

  • DeferredImportSelector(延期的的ImportSelector):ImportSelector的一种变体,在处理完所有@Configuration bean 后运行。当所选导入是@Conditional时,这种类型的选择器可能特别有用。
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

EnableAutoConfiguration上的 AutoConfigurationImportSelector就是这种类型。都说了在处理完所有@Configuration bean后才出处理DeferredImportSelector,所以这里的处理目前也很简单,就是包装了下放到了一个list集合中,真正的处理后续文章会说明(springboot starter)。(简化后代码)


public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(configClass, importSelector);
this.deferredImportSelectors.add(holder);
}
  • 非DeferredImportSelector类型处理方式:调用importSelector接口方法selectImports()结果作为importSourceClasses ,然后又重新调用processImports 方法递归处理。这里有一点可以注意下,就是实例化ImportSelector代码,selectImports()实现里可以添加扩展。

ImportBeanDefinitionRegistrar处理

存入ConfigurationClass属性Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars中,后续会做真正的处理。处理就在ConfigurationClassPostProcessor#processConfigBeanDefinitions方法中。

this.reader.loadBeanDefinitions(configClasses);

@Configuration类型处理

Configuration处理会调用ConfigurationClassParser#processConfigurationClass,文章开头红色标识的。是的又开始了新一轮的循环。这里只是作为@Configuration类型处理,并不是说这个类上非得加上@Configuration注解,普通的bean也是可以的。只不过后续的解析过程中没有解析到@Import、@Bean等 而已

最后

以上就是时尚睫毛膏为你收集整理的spring @Import介绍文档翻译何时解析@Import的全部内容,希望文章能够帮你解决spring @Import介绍文档翻译何时解析@Import所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部