栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring 源码执行BFPP invokeBeanFactoryPostProcessors-ConfigurationClassPostProcessor (2)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring 源码执行BFPP invokeBeanFactoryPostProcessors-ConfigurationClassPostProcessor (2)

上篇传送门
上篇介绍了component-scan标签的解析,把扫描到的@Component类文件扫描到,然后生成bean定义信息并注册到工厂,工厂注册完后,又注册了注解解析内部定义信息(后置处理器)以及监听器,接下来咱们继续看下是如何执行后置处理器的

了解ConfigurationClassPostProcessor之前,先看下关系图,实现了BDRPP、BFPP、PriorityOrdered接口,看到这里都会想到是在哪里进行处理了

咱们上篇了解到spring只是注册了bean的定义信息,对于internal*对应的类并没有进行实例化,那执行BFPP的时候就必须先创建出bean对象(后面咱们会详细聊,这里先不展开),然后进行调用

文章知识点
    注解什么时候解析的BDRPP处理了哪些注解注解标注的类实例化了吗
PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors 执行BDRPP
private static void invokeBeanDefinitionRegistryPostProcessors(Collection postProcessors, BeanDefinitionRegistry registry) {
	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		//执行对应的接口方法
		postProcessor.postProcessBeanDefinitionRegistry(registry);
	}
}
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry 执行模板方法
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	//记录符合条件的bean定义信息包装类
	List configCandidates = new ArrayList<>();
	//获取所有的bean定义信息
	String[] candidateNames = registry.getBeanDefinitionNames();
	for (String beanName : candidateNames) {
		BeanDefinition beanDef = registry.getBeanDefinition(beanName);
		//判断是否已经当作配置类处理过
		if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
			}
		// 检查是否符合条件
		// 规则:@Component、@ComponentScan、@import、@importResource、@Bean修饰的bean定义
		}else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}
	// 如果没有符合条件的,直接返回了,说明这个项目比较老,基本是依靠xml方式配置的
	if (configCandidates.isEmpty()) {
		return;
	}
	// checkConfigurationClassCandidate方法进行判断的时候最后进行order值获取,并赋值了,这里进行排序
	configCandidates.sort((bd1, bd2) -> {
		int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
		int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
		return Integer.compare(i1, i2);
	});
	// Detect any custom bean name generation strategy supplied through the enclosing application context
	SingletonBeanRegistry sbr = null;
	// 这里的registry默认是DefaultListableBeanFactory
	// 不了解类关系的 可以查下前面文章,spring大体了解 https://blog.csdn.net/xiaomengxin521/article/details/123277648
	if (registry instanceof SingletonBeanRegistry) {
		sbr = (SingletonBeanRegistry) registry;
		// 如果不存在自定义bean名称生成器
		if (!this.localBeanNameGeneratorSet) {
			// 尝试获取并设置
			BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
			if (generator != null) {
				this.componentScanBeanNameGenerator = generator;
				this.importBeanNameGenerator = generator;
			}
		}
	}
	//保证环境信息(后面会对咱们的占位符进行赋值)
	if (this.environment == null) {
		this.environment = new StandardEnvironment();
	}

	// 创建一个解析对象
	ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);
	// 定义一个容器,用于存放解析出来的bean定义信息
	Set candidates = new linkedHashSet<>(configCandidates);
	//用于存储已经解析过的对象
	Set alreadyParsed = new HashSet<>(configCandidates.size());
	do {
		// 解析带有@Controller、@import、@importResource、@ComponentScan、@ComponentScans、@Bean的Bean定义信息
		parser.parse(candidates);
		parser.validate();
		// 存储解析的bean定义信息
		Set configClasses = new linkedHashSet<>(parser.getConfigurationClasses());
		// 删除掉已经解析过的,用新的
		configClasses.removeAll(alreadyParsed);

		// Read the model and create bean definitions based on its content
		if (this.reader == null) {
			this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getimportRegistry());
		}
		// 注册bean定义信息到工厂,方便实例化
		this.reader.loadBeanDefinitions(configClasses);
		alreadyParsed.addAll(configClasses);

		candidates.clear();
		// 如果新注册了bean定义信息
		if (registry.getBeanDefinitionCount() > candidateNames.length) {
			// 获取解析加载后的bean定义信息
			String[] newCandidateNames = registry.getBeanDefinitionNames();
			// 加载之前的bean定义信息
			Set oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
			// 已经解析过的
			Set alreadyParsedClasses = new HashSet<>();
			for (ConfigurationClass configurationClass : alreadyParsed) {
				alreadyParsedClasses.add(configurationClass.getmetadata().getClassName());
			}
			for (String candidateName : newCandidateNames) {
				// 如果是新加载的
				if (!oldCandidateNames.contains(candidateName)) {
					BeanDefinition bd = registry.getBeanDefinition(candidateName);
					// 符合条件添加到容器继续解析
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) {
						candidates.add(new BeanDefinitionHolder(bd, candidateName));
					}
				}
			}
			candidateNames = newCandidateNames;
		}
	}
	while (!candidates.isEmpty());

	// 注册通知
	if (sbr != null && !sbr.containsSingleton(import_REGISTRY_BEAN_NAME)) {
		sbr.registerSingleton(import_REGISTRY_BEAN_NAME, parser.getimportRegistry());
	}
	if (this.metadataReaderFactory instanceof CachingmetadataReaderFactory) {
		((CachingmetadataReaderFactory) this.metadataReaderFactory).clearCache();
	}
}
ConfigurationClassUtils.checkConfigurationClassCandidate

public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, metadataReaderFactory metadataReaderFactory) {
	// 获取全限定类名
	String className = beanDef.getBeanClassName();
	// 猜测是判断是正常流程的bean定义信息,像FactoryBean不进行解析
	if (className == null || beanDef.getFactoryMethodName() != null) {
		return false;
	}
	// 获取到注解信息
	Annotationmetadata metadata;
	// 如果属于注解标注的bean定义信息
	if (beanDef instanceof AnnotatedBeanDefinition && className.equals(((AnnotatedBeanDefinition) beanDef).getmetadata().getClassName())) {
		metadata = ((AnnotatedBeanDefinition) beanDef).getmetadata();
	}
	else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
		// 排除掉不能加载bean定义信息
		Class beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
		if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
				BeanPostProcessor.class.isAssignableFrom(beanClass) ||
				AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
				EventListenerFactory.class.isAssignableFrom(beanClass)) {
			return false;
		}
		metadata = Annotationmetadata.introspect(beanClass);
	}
	else {
		try {
			//强制去获去注解metadata 
			metadataReader metadataReader = metadataReaderFactory.getmetadataReader(className);
			metadata = metadataReader.getAnnotationmetadata();
		}catch (IOException ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Could not find class file for introspecting configuration annotations: " +className, ex);
			}
			// 如果强制拿不到直接返回false
			return false;
		}
	}
	Map config = metadata.getAnnotationAttributes(Configuration.class.getName());
	// 如果是Configuration注解修饰,并且是动态代理的,标识为 full
	if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
	}
	// isConfigurationCandidate 判断是否是@Component、@ComponentScan、@import、@importResource、@Bean注解修饰
	// 如果被@Configuration注解修改了,那么里面是可以配置@Bean,所以最后需要判断下
	// 如果是这些注解修饰的bean定义信息都会被标识为普通的对象 标识为 lite
	else if (config != null || isConfigurationCandidate(metadata)) {
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
	}else {
		return false;
	}

	// 到这里已经确定是注解修饰的bean,并且是被spring认可的正常流程创建的bean
	//获取order值赋给bean定义信息
	Integer order = getOrder(metadata);
	if (order != null) {
		beanDef.setAttribute(ORDER_ATTRIBUTE, order);
	}
	return true;
}
ConfigurationClassParser.processConfigurationClass
protected void processConfigurationClass(ConfigurationClass configClass,Predicate 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);
			}
			return;
		}
		else {
			this.configurationClasses.remove(configClass);
			this.knownSuperclasses.values().removeIf(configClass::equals);
		}
	}
	// 获取到类信息
	SourceClass sourceClass = asSourceClass(configClass, filter);
	do {
		// 开始执行配置类的解析
		sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
	}
	while (sourceClass != null);
	// 添加到缓存
	this.configurationClasses.put(configClass, configClass);
}
ConfigurationClassParser.doProcessConfigurationClass
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate filter)throws IOException {
	// 如果是@Component注解
	if (configClass.getmetadata().isAnnotated(Component.class.getName())) {
		// 需要递归进行解析内部的配置类
		processMemberClasses(configClass, sourceClass, filter);
	}

	// 解析 @PropertySource
	for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getmetadata(),PropertySources.class,org.springframework.context.annotation.PropertySource.class)) {
		if (this.environment instanceof ConfigurableEnvironment) {
			processPropertySource(propertySource);
		}else {
			logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getmetadata().getClassName() +"]. Reason: Environment must implement ConfigurableEnvironment");
		}
	}

	// 处理@ComponentScan注解
	Set componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getmetadata(), ComponentScans.class, ComponentScan.class);
	//验证是否符合条件
	if (!componentScans.isEmpty() &&!this.conditionevaluator.shouldSkip(sourceClass.getmetadata(), ConfigurationPhase.REGISTER_BEAN)) {
		for (AnnotationAttributes componentScan : componentScans) {
			// 扫描路径的对应的注解,并生成bean定义信息
			Set scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getmetadata().getClassName());
			for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
				BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
				if (bdCand == null) {
					bdCand = holder.getBeanDefinition();
				}
				// 验证是否有符合条件(上面有讲解)
				if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
					// 对扫描到的配置进行递归解析
					parse(bdCand.getBeanClassName(), holder.getBeanName());
				}
			}
		}
	}

	// 处理@import注解
	processimports(configClass, sourceClass, getimports(sourceClass), filter, true);

	// 处理@importResource
	AnnotationAttributes importResource =
			AnnotationConfigUtils.attributesFor(sourceClass.getmetadata(), importResource.class);
	if (importResource != null) {
		String[] resources = importResource.getStringArray("locations");
		Class readerClass = importResource.getClass("reader");
		for (String resource : resources) {
			String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
			configClass.addimportedResource(resolvedResource, readerClass);
		}
	}

	// 处理 @Bean 
	Set beanMethods = retrieveBeanMethodmetadata(sourceClass);
	for (Methodmetadata methodmetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodmetadata, configClass));
	}

	// 处理接口中的注解,1.8之后支持
	processInterfaces(configClass, sourceClass);

	// 处理父类
	if (sourceClass.getmetadata().hasSuperClass()) {
		String superclass = sourceClass.getmetadata().getSuperClassName();
		if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
			this.knownSuperclasses.put(superclass, configClass);
			// 返回父类,然后继续解析父类
			return sourceClass.getSuperClass();
		}
	}
	return null;
}
ConfigurationClassParser.processMemberClasses 解析@Component
@Component
public class CommonConfig {
	@Component
	class InnerClass{
		
		@Component
		class InnerInnerClass{
		
		} 
	} 
}
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,Predicate filter) throws IOException {
	// 获取@Component内部配置类
	Collection memberClasses = sourceClass.getMemberClasses();
	if (!memberClasses.isEmpty()) {
		List candidates = new ArrayList<>(memberClasses.size());
		for (SourceClass memberClass : memberClasses) {
			if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getmetadata()) &&!memberClass.getmetadata().getClassName().equals(configClass.getmetadata().getClassName())) {
				//符合条件添加到容器中,用于递归解析
				candidates.add(memberClass);
			}
		}
		// 配置的注解类是可以添加@Order注解的,这里对Order进行排序
		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 {
					// 递归解析
					processConfigurationClass(candidate.asConfigClass(configClass), filter);
				}finally {
					// 添加递归标示 (弹出)
					this.importStack.pop();
				}
			}
		}
	}
}
ConfigurationClassParser.processPropertySource 解析@PropertySource并把配置文件加载到propertySourceList
@Configuration // 这里必须要添加
@PropertySource(value = "application.properties")
public class CommonConfig {
}
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
	// 获取@PropertySource 属性值
	String name = propertySource.getString("name");
	if (!StringUtils.hasLength(name)) {
		name = null;
	}
	String encoding = propertySource.getString("encoding");
	if (!StringUtils.hasLength(encoding)) {
		encoding = null;
	}
	// 获取value值 value=“classpath*:*.properties”
	String[] locations = propertySource.getStringArray("value");
	Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
	boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
	Class factoryClass = propertySource.getClass("factory");
	//得到资源工厂
	PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));

	for (String location : locations) {
		try {
			// 处理占位符
			String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
			Resource resource = this.resourceLoader.getResource(resolvedLocation);
			// 解析配置文件,把解析出的配置文件加载到 propertySourceList
			addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
		}catch (IllegalArgumentException | FileNotFoundException | UnknownHostException | SocketException ex) {
			if (ignoreResourceNotFound) {
				if (logger.isInfoEnabled()) {
					logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
				}
			}else {
				throw ex;
			}
		}
	}
}
ConfigurationClassParser.getimports 获取到@import所加载的资源
private Set getimports(SourceClass sourceClass) throws IOException {
	// 存放加载的资源类
	Set imports = new linkedHashSet<>();
	// 递归标识
	Set visited = new linkedHashSet<>();
	// 处理@import注解导入的类
	collectimports(sourceClass, imports, visited);
	return imports;
}
ConfigurationClassParser.getimports 递归获取@import注解标注的类
private void collectimports(SourceClass sourceClass, Set imports, Set visited)throws IOException {
	if (visited.add(sourceClass)) {
		for (SourceClass annotation : sourceClass.getAnnotations()) {
			String annName = annotation.getmetadata().getClassName();
			if (!annName.equals(import.class.getName())) {
				// 如果存在多层嵌套关系,那么进行递归获取
				collectimports(annotation, imports, visited);
			}
		}
		// 把@import 标注的类添加到集合中
		imports.addAll(sourceClass.getAnnotationAttributes(import.class.getName(), "value"));
	}
}
ConfigurationClassParser.processimports 解析@
private void processimports(ConfigurationClass configClass, SourceClass currentSourceClass,Collection importCandidates, Predicate exclusionFilter,boolean checkForCircularimports) {
	
	if (importCandidates.isEmpty()) {
		return;
	}

	if (checkForCircularimports && isChainedimportOnStack(configClass)) {
		this.problemReporter.error(new CircularimportProblem(configClass, this.importStack));
	}
	else {
		this.importStack.push(configClass);
		try {
			// 循环前面扫描到的所有@import标注的类
			for (SourceClass candidate : importCandidates) {
				// 如果属于importSelector ,
				if (candidate.isAssignable(importSelector.class)) {
					// 创建实例
					Class candidateClass = candidate.loadClass();
					importSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, importSelector.class,this.environment, this.resourceLoader, this.registry);
					// 获取过滤器
					Predicate selectorFilter = selector.getExclusionFilter();
					if (selectorFilter != null) {
						exclusionFilter = exclusionFilter.or(selectorFilter);
					}
					// 如果需要延期处理的话,添加到容器中
					if (selector instanceof DeferredimportSelector) {
						this.deferredimportSelectorHandler.handle(configClass, (DeferredimportSelector) selector);
					}else {
						//不需要延期处理,那么进行递归处理(@import类下有可能还有@import)
						String[] importClassNames = selector.selectimports(currentSourceClass.getmetadata());
						Collection importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
						processimports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
					}
				}else if (candidate.isAssignable(importBeanDefinitionRegistrar.class)) {
					// 处理 importBeanDefinitionRegistrar类型
					Class candidateClass = candidate.loadClass();
					importBeanDefinitionRegistrar registrar = ParserStrategyUtils.instantiateClass(candidateClass, importBeanDefinitionRegistrar.class,this.environment, this.resourceLoader, this.registry);
					configClass.addimportBeanDefinitionRegistrar(registrar, currentSourceClass.getmetadata());
				}else {
					// 当作配置类进行处理 @Configuration
					this.importStack.registerimport(currentSourceClass.getmetadata(), candidate.getmetadata().getClassName());
					processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
				}
			}
		}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();
		}
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/775100.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号