@Import注解主要用于引入另外一个@Configuration。和Spring XML配置文件中的标签功能一样。
// ConfigurationClassParser.class 302行 // 处理@Import注解,请注意参数内部的getImports方法 processImports(configClass, sourceClass, getImports(sourceClass), true); private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException { Set<SourceClass> imports = new LinkedHashSet<>(); Set<SourceClass> visited = new LinkedHashSet<>(); collectImports(sourceClass, imports, visited); return imports; } // 递归获取@Import注解 private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited) throws IOException { // 添加已处理的避免无限递归 if (visited.add(sourceClass)) { // 获取传入资源上的注解列表 for (SourceClass annotation : sourceClass.getAnnotations()) { // 获取注解名称 String annName = annotation.getMetadata().getClassName(); // 若当前注解不是@Import则递归查找 if (!annName.equals(Import.class.getName())) { collectImports(annotation, imports, visited); } } // 添加已经获取的所有注解 imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value")); } } private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, boolean checkForCircularImports) { if (importCandidates.isEmpty()) { return; } if (checkForCircularImports && isChainedImportOnStack(configClass)) { this.problemReporter.error(new CircularImportProblem(configClass, this.importStack)); } else { this.importStack.push(configClass); try { for (SourceClass candidate : importCandidates) { // 是否是ImportSelector的实现 if (candidate.isAssignable(ImportSelector.class)) { // Candidate class is an ImportSelector -> delegate to it to determine imports Class<?> candidateClass = candidate.loadClass(); ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class); ParserStrategyUtils.invokeAwareMethods(selector, this.environment, this.resourceLoader, this.registry); if (selector instanceof DeferredImportSelector) { this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector); } else { String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames); processImports(configClass, currentSourceClass, importSourceClasses, false); } } // 是否是ImportBeanDefinitionRegistrar的实现 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 = BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class); ParserStrategyUtils.invokeAwareMethods(registrar, this.environment, this.resourceLoader, this.registry); configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); } // 都不是的话把它当做@Configuration来处理 else { // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar -> // process it as an @Configuration class this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName()); // 将其作为@Configuration处理 processConfigurationClass(candidate.asConfigClass(configClass)); } } } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", ex); } finally { this.importStack.pop(); } } }【SpringBoot源码分析】-Bean的加载过程 (9)
内容版权声明:除非注明,否则皆为本站原创文章。