首页 > 编程语言 >Spring源码-12-配置类解析器ConfigurationClassParser

Spring源码-12-配置类解析器ConfigurationClassParser

时间:2022-12-16 16:34:37浏览次数:58  
标签:解析器 configClass 12 java String 配置 源码 class sourceClass

Spring源码-12-配置类解析器ConfigurationClassParser

解析配置类

// ConfigurationClassParser.java
public void parse(Set<BeanDefinitionHolder> configCandidates) {
		for (BeanDefinitionHolder holder : configCandidates) {
			BeanDefinition bd = holder.getBeanDefinition();
			try {
				if (bd instanceof AnnotatedBeanDefinition) {
					this.parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
				}
				else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
					this.parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
				}
				else {
					parse(bd.getBeanClassName(), holder.getBeanName());
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
			}
		}

		/**
		 * 处理延迟ImportSelector
		 */
		this.deferredImportSelectorHandler.process();
	}
// ConfigurationClassParser.java
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
		if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
			return;
		}

		ConfigurationClass existingClass = this.configurationClasses.get(configClass);
		if (existingClass != null) {
			if (configClass.isImported()) {
				if (existingClass.isImported()) {
					existingClass.mergeImportedBy(configClass);
				}
				// Otherwise ignore new imported config class; existing non-imported class overrides it.
				return;
			}
			else {
				// Explicit bean definition found, probably replacing an import.
				// Let's remove the old one and go with the new one.
				this.configurationClasses.remove(configClass);
				this.knownSuperclasses.values().removeIf(configClass::equals);
			}
		}

		// Recursively process the configuration class and its superclass hierarchy.
		SourceClass sourceClass = asSourceClass(configClass, filter);
		/**
		 * 显式继承场景
		 *     - 配置类没有父类 返回null
		 *     - 配置类有父类 返回父类 递归解析父类
		 */
		do {
			sourceClass = this.doProcessConfigurationClass(configClass, sourceClass, filter);
		}
		while (sourceClass != null);

		this.configurationClasses.put(configClass, configClass);
	}
// ConfigurationClassParser.java
@Nullable
	protected final SourceClass doProcessConfigurationClass(
			ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
			throws IOException {

		/**
		 * @Configuration是组合注解
		 *     - @Component
		 */
		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			// Recursively process any member (nested) classes first
			/**
			 * 配置的内部类
			 *     - 内部类也是配置类 dfs解析下去
			 */
			this.processMemberClasses(configClass, sourceClass, filter);
		}

		// Process any @PropertySource annotations
		/**
		 * 配置类上的@PropertySource解析
		 *     - 单个@PropertySource
		 *     - 多个@PropertySource
		 *     - @PropertySources定义的多个@PropertySource
		 * for轮询中处理每个@PropertySource
		 * 将@PrepertySource指定的配置文件解析加载到Environment中
		 */
		for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), PropertySources.class,
				org.springframework.context.annotation.PropertySource.class)) {
			if (this.propertySourceRegistry != null) {
				this.propertySourceRegistry.processPropertySource(propertySource); // 处理每个@PropertySource
			}
			else {
				logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
						"]. Reason: Environment must implement ConfigurableEnvironment");
			}
		}

		// Process any @ComponentScan annotations
		/**
		 * 配置类上的@ComponentScan注解解析
		 *     - 单个@CompoentScan
		 *     - 多个@ComponentScan
		 *     - @ComponentScans定义的多个@ComponentScan
		 * - 扫包路径下@Component/类@Component的类封装BeanDefinition注册进Bean工厂
		 * - 扫描到的配置类递归继续解析
		 */
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			for (AnnotationAttributes componentScan : componentScans) {
				// The config class is annotated with @ComponentScan -> perform the scan immediately
				/**
				 * 扫包路径下符合要求的类被封装成ScannedGenericBeanDefinition
				 *     - @Component/类@Component注解标识的类
				 */
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); // 配置类名称
				// Check the set of scanned definitions for any further config classes and parse recursively if needed
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) { // 扫包出来的BeanDefinition可能本身也是配置类
					BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
					if (bdCand == null) {
						bdCand = holder.getBeanDefinition();
					}
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { // 扫到的类也是配置类就继续递归解析下去
						this.parse(bdCand.getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

		// Process any @Import annotations
		/**
		 * @Import注解的配置类
		 * getImports(...)找出配置类上通过@Import注解导入的的所有类
		 * 解析@Import注解导入的类 根据导入的类进行不同的策略处理
		 *     - ImportSelector的实现
		 *         - selectImports(...)定义的类按照Import类递归解析
		 *     - ImportBeanDefinitionRegistrar的实现
		 *         - 将ImportBeanDefinitionRegistrar缓存到配置类的importBeanDefinitionRegistrars
		 *     - 没有实现ImportSelector和ImportBeanDefinitionRegistry接口的类
		 *         - 配置类就递归解析下去
		 *         - 普通类就缓存到imports哈希表中
		 *             - 不发生注册Bean工厂
		 */
		this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);

		// Process any @ImportResource annotations
		/**
		 * @ImportResource引入的配置文件
		 * 将@ImportResource指定的配置文件资源缓存在配置类的importedResources中
		 */
		AnnotationAttributes importResource =
				AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); // 配置上的@ImportResource注解对象
		if (importResource != null) {
			String[] resources = importResource.getStringArray("locations"); // 指定的配置文件路径
			Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
			for (String resource : resources) {
				String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
				configClass.addImportedResource(resolvedResource, readerClass); // 缓存在配置类的importedResources中
			}
		}

		// Process individual @Bean methods
		/**
		 * @Bean注解的方法
		 * 将@Bean注解的方法缓存在配置类的beanMethods中
		 */
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); // 配置类被@Bean标识的方法
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); // 缓存在配置类的beanMethods中
		}

		// Process default methods on interfaces
		processInterfaces(configClass, sourceClass);

		// Process superclass, if any
		if (sourceClass.getMetadata().hasSuperClass()) {
			String superclass = sourceClass.getMetadata().getSuperClassName();
			if (superclass != null && !superclass.startsWith("java") &&
					!this.knownSuperclasses.containsKey(superclass)) {
				this.knownSuperclasses.put(superclass, configClass);
				// Superclass found, return its annotation metadata and recurse
				return sourceClass.getSuperClass();
			}
		}

		// No superclass -> processing is complete
		return null;
	}

一 内部类

配置中的内部类也是配置类就递归下去

// ConfigurationClassParser.java
/**
			 * 配置的内部类
			 *     - 内部类也是配置类 dfs解析下去
			 */
			this.processMemberClasses(configClass, sourceClass, filter);
// ConfigurationClassParser.java
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,
			Predicate<String> filter) throws IOException {

		Collection<SourceClass> memberClasses = sourceClass.getMemberClasses(); // 配置类的内部类
		if (!memberClasses.isEmpty()) {
			List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
			for (SourceClass memberClass : memberClasses) {
				if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
						!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
					candidates.add(memberClass); // 内部类也是配置类 缓存起来
				}
			}
			OrderComparator.sort(candidates);
			for (SourceClass candidate : candidates) {
				if (this.importStack.contains(configClass)) {
					this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
				}
				else {
					this.importStack.push(configClass); // 入栈出栈解决多层嵌套内部类场景
					try {
						this.processConfigurationClass(candidate.asConfigClass(configClass), filter); // 解析配置类
					}
					finally {
						this.importStack.pop();
					}
				}
			}
		}
	}

二 @PropertySource

将资源文件中的配置加载到Environment中

  • @PropertySource
  • @PropertySources
// ConfigurationClassParser.java
this.propertySourceRegistry.processPropertySource(propertySource); // 处理每个@PropertySource
// PropertySourceRegistry.java
void processPropertySource(AnnotationAttributes propertySource) throws IOException { // 读取@PropertySource注解元素中的值
		String name = propertySource.getString("name"); // @PropertySource的name值
		if (!StringUtils.hasLength(name)) {
			name = null;
		}
		String encoding = propertySource.getString("encoding"); // @PropertySource的encoding值
		if (!StringUtils.hasLength(encoding)) {
			encoding = null;
		}
		String[] locations = propertySource.getStringArray("value"); // @PropertySource的locations值 配置文件路径
		Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
		boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");

		Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
		Class<? extends PropertySourceFactory> factorClassToUse =
				(factoryClass != PropertySourceFactory.class ? factoryClass : null);
		PropertySourceDescriptor descriptor = new PropertySourceDescriptor(Arrays.asList(locations), ignoreResourceNotFound, name,
				factorClassToUse, encoding); // 封装@PropertySource注解元素中的值
		this.propertySourceProcessor.processPropertySource(descriptor);
		this.descriptors.add(descriptor);
	}
// PropertySourceRegistry.java
public void processPropertySource(PropertySourceDescriptor descriptor) throws IOException {
		String name = descriptor.name();
		String encoding = descriptor.encoding();
		List<String> locations = descriptor.locations();
		Assert.isTrue(locations.size() > 0, "At least one @PropertySource(value) location is required");
		boolean ignoreResourceNotFound = descriptor.ignoreResourceNotFound();
		PropertySourceFactory factory = (descriptor.propertySourceFactory() != null
				? instantiateClass(descriptor.propertySourceFactory())
				: DEFAULT_PROPERTY_SOURCE_FACTORY);

		for (String location : locations) { // 配置在@PropertySource中的配置文件路径
			try {
				String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
				Resource resource = this.resourceLoader.getResource(resolvedLocation);
				this.addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding))); // 配置文件配置项加载到Environment中
			}
			catch (IllegalArgumentException | FileNotFoundException | UnknownHostException | SocketException ex) {
				// Placeholders not resolvable or resource not found when trying to open it
				if (ignoreResourceNotFound) {
					if (logger.isInfoEnabled()) {
						logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
					}
				}
				else {
					throw ex;
				}
			}
		}
	}
// PropertySourceProcessor.java
private void addPropertySource(org.springframework.core.env.PropertySource<?> propertySource) {
		String name = propertySource.getName();
		MutablePropertySources propertySources = this.environment.getPropertySources(); // 将配置文件中的配置加载到environment中

		if (this.propertySourceNames.contains(name)) {
			// We've already added a version, we need to extend it
			org.springframework.core.env.PropertySource<?> existing = propertySources.get(name);
			if (existing != null) {
				PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
						((ResourcePropertySource) propertySource).withResourceName() : propertySource);
				if (existing instanceof CompositePropertySource) {
					((CompositePropertySource) existing).addFirstPropertySource(newSource);
				}
				else {
					if (existing instanceof ResourcePropertySource) {
						existing = ((ResourcePropertySource) existing).withResourceName();
					}
					CompositePropertySource composite = new CompositePropertySource(name);
					composite.addPropertySource(newSource);
					composite.addPropertySource(existing);
					propertySources.replace(name, composite);
				}
				return;
			}
		}

		if (this.propertySourceNames.isEmpty()) {
			propertySources.addLast(propertySource);
		}
		else {
			String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
			propertySources.addBefore(firstProcessed, propertySource);
		}
		this.propertySourceNames.add(name);
	}

三 @ComponentScan

定义扫包路径

  • @ComponentScan
  • @ComponentScans

筛选出符合过滤规则(类Component)的类注册Bean工厂,配置类递归解析

1 扫包路径下类Component

// ConfigurationClassParser.java
/**
				 * 扫包路径下符合要求的类被封装成ScannedGenericBeanDefinition
				 *     - @Component/类@Component注解标识的类
				 */
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); // 配置类名称
// ComponentScanAnnotationParser.java
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) {
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
				componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

		Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
		boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
		scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
				BeanUtils.instantiateClass(generatorClass));

		ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
		if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
			scanner.setScopedProxyMode(scopedProxyMode);
		}
		else {
			Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
			scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
		}

		scanner.setResourcePattern(componentScan.getString("resourcePattern"));

		for (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) {
			List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,
					this.resourceLoader, this.registry);
			for (TypeFilter typeFilter : typeFilters) {
				scanner.addIncludeFilter(typeFilter);
			}
		}
		for (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) {
			List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,
				this.resourceLoader, this.registry);
			for (TypeFilter typeFilter : typeFilters) {
				scanner.addExcludeFilter(typeFilter);
			}
		}

		boolean lazyInit = componentScan.getBoolean("lazyInit");
		if (lazyInit) {
			scanner.getBeanDefinitionDefaults().setLazyInit(true);
		}

		Set<String> basePackages = new LinkedHashSet<>();
		String[] basePackagesArray = componentScan.getStringArray("basePackages"); // @ComponentScan中定义的扫包路径
		for (String pkg : basePackagesArray) {
			String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
					ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
			Collections.addAll(basePackages, tokenized);
		}
		for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
			basePackages.add(ClassUtils.getPackageName(clazz));
		}
		if (basePackages.isEmpty()) {
			basePackages.add(ClassUtils.getPackageName(declaringClass));
		}

		scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
			@Override
			protected boolean matchClassName(String className) {
				return declaringClass.equals(className);
			}
		});
		return scanner.doScan(StringUtils.toStringArray(basePackages)); // 扫描指定扫包路径 @Component/类@Component标识的类封装成BeanDefnition注册到Bean工厂
	}
// ClassPathBeanDefinitionScanner.java
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
		for (String basePackage : basePackages) {
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage); // 定义的扫包路径下被@Component标识的类被封装成ScannedGenericBeanDefinition
			for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					registerBeanDefinition(definitionHolder, this.registry); // BeanDefinition注册到Bean工厂
				}
			}
		}
		return beanDefinitions;
	}
1.1 @Component/类@Component注解的类
// ClassPathBeanDefinitionScanner.java
Set<BeanDefinition> candidates = super.findCandidateComponents(basePackage); // 定义的扫包路径下被@Component标识的类被封装成ScannedGenericBeanDefinition
// ClassPathScanningCandidateComponentProvider.java
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
		if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
			return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
		}
		else {
			return this.scanCandidateComponents(basePackage);
		}
	}
// ClassPathScanningCandidateComponentProvider.java
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
			boolean traceEnabled = logger.isTraceEnabled();
			boolean debugEnabled = logger.isDebugEnabled();
			for (Resource resource : resources) {
				String filename = resource.getFilename();
				if (filename != null && filename.contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
					// Ignore CGLIB-generated classes in the classpath
					continue;
				}
				if (traceEnabled) {
					logger.trace("Scanning " + resource);
				}
				try {
					MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
					if (this.isCandidateComponent(metadataReader)) { // 扫包路径下的@Component或者类@Component标识的类才会被封装成Definition
						ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); // BeanDefinition的实现标识是扫描出来的类封装的
						sbd.setSource(resource);
						if (isCandidateComponent(sbd)) {
							if (debugEnabled) {
								logger.debug("Identified candidate component class: " + resource);
							}
							candidates.add(sbd);
						}
						else {
							if (debugEnabled) {
								logger.debug("Ignored because not a concrete top-level class: " + resource);
							}
						}
					}
					else {
						if (traceEnabled) {
							logger.trace("Ignored because not matching any filter: " + resource);
						}
					}
				}
				catch (FileNotFoundException ex) {
					if (traceEnabled) {
						logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());
					}
				}
				catch (Throwable ex) {
					throw new BeanDefinitionStoreException(
							"Failed to read candidate component class: " + resource, ex);
				}
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
		}
		return candidates;
	}
1.2 BeanDefinition注册Bean工厂
// ClassPathBeanDefinitionScanner.java
registerBeanDefinition(definitionHolder, this.registry); // BeanDefinition注册到Bean工厂

2 递归解析配置类

// ConfigurationClassParser.java
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { // 扫到的类也是配置类就继续递归解析下去
						this.parse(bdCand.getBeanClassName(), holder.getBeanName());
					}

四 @Import

// ConfigurationClassParser.java
/**
		 * @Import注解的配置类
		 * getImports(...)找出配置类上通过@Import注解导入的的所有类
		 * 解析@Import注解导入的类 根据导入的类进行不同的策略处理
		 *     - ImportSelector的实现
		 *         - selectImports(...)定义的类按照Import类递归解析
		 *     - ImportBeanDefinitionRegistrar的实现
		 *         - 将ImportBeanDefinitionRegistrar缓存到配置类的importBeanDefinitionRegistrars
		 *     - 没有实现ImportSelector和ImportBeanDefinitionRegistry接口的类
		 *         - 配置类就递归解析下去
		 *         - 普通类就缓存到imports哈希表中
		 *             - 不发生注册Bean工厂
		 */
		this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);
// ConfigurationClassParser.java
/**
	 * @Import进来的类
	 *     - 实现了ImportSelector
	 *         - 递归解析通过selectImports(...)进来的所有类
	 *     - 实现了ImportBeanDefinitionRegistrar
	 *         - 将ImportBeanDefinitionRegistrar缓存到importBeanDefinitionRegistrars
	 *     - 没有实现ImportSelector ImportBeanDefinitionRegistry
	 *         - 当成配置类贪心解析一次
	 *             - 如果仅仅是一个普通类 不会发生注册Bean工厂
	 */
	private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
			boolean checkForCircularImports) {

		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		}
		else {
			this.importStack.push(configClass); // 递归栈 import进来的类本身又有@Import
			try {
				for (SourceClass candidate : importCandidates) { // import的类
					if (candidate.isAssignable(ImportSelector.class)) { // ImportSelector接口的实现
						// 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); // 实现类对ImportSelector声明的方法具体实现
						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()); // selectImports(...)方法的返回值
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
							this.processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false); // 递归解析ImportSelector定义的所有的类
						}
					}
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) { // ImportBeanDefinitionRegistrar接口的实现
						// 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()); // 将ImportBeanDefinitionRegistrar缓存到importBeanDefinitionRegistrars
					}
					else { // 把它当成配置类再解析一次 如果仅仅是import了普通类 并不会发生注册Bean工厂
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
						// process it as an @Configuration class
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						this.processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter); // 当成配置类进行解析 在配置类的imported中缓存主动import的类 记录当前类是被谁import进来的
					}
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to process import candidates for configuration class [" +
						configClass.getMetadata().getClassName() + "]: " + ex.getMessage(), ex);
			}
			finally {
				this.importStack.pop();
			}
		}
	}

对import的类进行解析

  • ImportSelector实现
  • ImportBeanDefinitionRegistry实现
  • 普通类

1 ImportSelector的实现

// ConfigurationClassParser.java
this.processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false); // 递归解析ImportSelector定义的所有的类

2 ImportBeanDefinitionRegistrar的实现

// ConfigurationClassParser.java
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); // 将ImportBeanDefinitionRegistrar缓存到importBeanDefinitionRegistrars

3 没有实现ImportSelector和ImportBeanDefinitionRegistrar

// ConfigurationClassParser.java
this.processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter); // 当成配置类进行解析 在配置类的imported中缓存主动import的类 记录当前类是被谁import进来的

五 @ImportResource

// ConfigurationClassParser.java
/**
		 * @ImportResource引入的配置文件
		 * 将@ImportResource指定的配置文件资源缓存在配置类的importedResources中
		 */
		AnnotationAttributes importResource =
				AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); // 配置上的@ImportResource注解对象
		if (importResource != null) {
			String[] resources = importResource.getStringArray("locations"); // 指定的配置文件路径
			Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
			for (String resource : resources) {
				String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
				configClass.addImportedResource(resolvedResource, readerClass); // 缓存在配置类的importedResources中
			}
		}
// ConfigurationClass.java
void addImportedResource(String importedResource, Class<? extends BeanDefinitionReader> readerClass) {
		this.importedResources.put(importedResource, readerClass);
	}

六 @Bean

// ConfigurationClassParser.java
/**
		 * @Bean注解的方法
		 * 将@Bean注解的方法缓存在配置类的beanMethods中
		 */
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); // 配置类被@Bean标识的方法
		for (MethodMetadata methodMetadata : beanMethods) {
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); // 缓存在配置类的beanMethods中
		}
// ConfigurationClass.java
void addBeanMethod(BeanMethod method) {
		this.beanMethods.add(method);
	}

标签:解析器,configClass,12,java,String,配置,源码,class,sourceClass
From: https://www.cnblogs.com/miss-u/p/16987726.html

相关文章