Spring核心后置处理器ConfigurationClassPostProcessor

ConfigurationClassPostProcessor类层次

这个后置处理器是spring的核心处理器,注解@ComponentScans @Configuration @Component @ComponentScan @Import @ImportResource @Lazy @Primary @DependsOn @Role @Description 等注解都是由这个类触发进行处理后注册元数据到容器中的。
在这里插入图片描述
该类实现了BeanDefinitionRegistryPostProcessor接口,该接口继承了BeanFactoryPostProcessor接口。前一个接口方法实现可以注册Bean的定义信息,后者的实现可以干预BeanFactory的创建。这两个接口的实现方法是核心方法,特别是注册的方法。

postProcessBeanDefinitionRegistry方法(核心)

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	int registryId = System.identityHashCode(registry);
	//省略校验代码.....
	this.registriesPostProcessed.add(registryId);
	//调用处理方法
	processConfigBeanDefinitions(registry);
}

processConfigBeanDefinitions方法

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
	//拿到所有的候选组件名称(用户定义的就只有启动类,启动类是扫描的入口)
	String[] candidateNames = registry.getBeanDefinitionNames();

	for (String beanName : candidateNames) {
		BeanDefinition beanDef = registry.getBeanDefinition(beanName);
		if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
				ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
			}
		}
		//判断是不是配置类型(以下注解标记的类是配置类型):
			//@Configuration注解标记的类是配置类,Bean定义信息被标记为full 类型
			//注解@Component @ComponentScan @Import	@ImportResource 标记的类是配置类,Bean定义信息被标记为lite 类型
			//类中的方法别@Bean注解标记,则也是配置类,Bean定义信息被标记为lite 类型
		else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			//存到候选组件集合中
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}

	//经过以上筛选,一般候选组件只剩下启动类
	if (configCandidates.isEmpty()) {
		return;
	}

	//按照order排序
	configCandidates.sort((bd1, bd2) -> {
		int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
		int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
		return Integer.compare(i1, i2);
	});

	// 获取自定义的Bean名称生产策略
	SingletonBeanRegistry sbr = null;
	if (registry instanceof SingletonBeanRegistry) {
		sbr = (SingletonBeanRegistry) registry;
		if (!this.localBeanNameGeneratorSet) {
			BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
			if (generator != null) {
				this.componentScanBeanNameGenerator = generator;
				this.importBeanNameGenerator = generator;
			}
		}
	}

	if (this.environment == null) {
		this.environment = new StandardEnvironment();
	}

	//生成解析器解析每一个配置类,实例内部封装了componentScanParser解析器,用来解析@ComponentScan注解
	ConfigurationClassParser parser = new ConfigurationClassParser(
			this.metadataReaderFactory, this.problemReporter, this.environment,
			this.resourceLoader, this.componentScanBeanNameGenerator, registry);

	Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
	Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
	do {
		//解析各种注解成Bean定义信息(核心关注逻辑)
		parser.parse(candidates);
		parser.validate();

		Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
		configClasses.removeAll(alreadyParsed);

		if (this.reader == null) {
			this.reader = new ConfigurationClassBeanDefinitionReader(
					registry, this.sourceExtractor, this.resourceLoader, this.environment,
					this.importBeanNameGenerator, parser.getImportRegistry());
		}
		
		//注册所有通过Import方式导入的BeanDefinitions,包含执行Condition的过滤逻辑
		this.reader.loadBeanDefinitions(configClasses);
		alreadyParsed.addAll(configClasses);

		candidates.clear();
		if (registry.getBeanDefinitionCount() > candidateNames.length) {
			String[] newCandidateNames = registry.getBeanDefinitionNames();
			Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
			Set<String> 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();
	}
}

该方法里面递归调用和嵌套逻辑很多,重点关注方法:

  1. ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) 这个方法判断是否是配置类,并且设置配置类是full还是lite类别的属性,这个这两种类别后续再写文章介绍。
  2. parser.parse(candidates) 这个方法里面有全部的解析逻辑,最为关键的方法
  3. this.reader.loadBeanDefinitions(configClasses)加载注册BeanDefinition的方法,该方法只注册通过@Import注解导入的Bean,其余的在解析过程中已经注册了。

pase方法的过渡处理逻辑

public void parse(Set<BeanDefinitionHolder> configCandidates) {
	this.deferredImportSelectors = new LinkedList<>();

	for (BeanDefinitionHolder holder : configCandidates) {
		BeanDefinition bd = holder.getBeanDefinition();
		try {
			if (bd instanceof AnnotatedBeanDefinition) {
				parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
			}
			else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
				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);
		}
	}
	//处理@Import解析过程城中缓存的ConfigurationClassParser类中的全局变量deferredImportSelectors,该类引导后递归解析spring定义的导入类,Spring自动配置类都由此导入
	processDeferredImportSelectors();
}

跟踪解析的流程调用到以下方法:

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
	if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
		return;
	}
	
	//判断该类是否是@import注解导入的且被解析过
	ConfigurationClass existingClass = this.configurationClasses.get(configClass);
	if (existingClass != null) {
		if (configClass.isImported()) {
			if (existingClass.isImported()) {
				//存入ConfigurationClass类的成员变量importedBy中,后续加载BeanDefinition的时候会判断是否需要跳过
				existingClass.mergeImportedBy(configClass);
			}
			return;
		}else {
			this.configurationClasses.remove(configClass);
			this.knownSuperclasses.values().removeIf(configClass::equals);
		}
	}
	SourceClass sourceClass = asSourceClass(configClass);
	do {
		//ConfigurationClassParser解析的最底层调用的方法,核心方法
		sourceClass = doProcessConfigurationClass(configClass, sourceClass);
	}
	while (sourceClass != null);
	//存放解析后的配置类
	this.configurationClasses.put(configClass, configClass);
}

解析的核心方法doProcessConfigurationClass

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
		throws IOException {

	//先递归地处理任何成员(嵌套内部类)类,必须是一个配置类(full或者lite的模式)
	processMemberClasses(configClass, sourceClass);

	//处理@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.warn("....");
		}
	}

	//处理@ComponentScan注解,什么都不配置则默认从启动类包开始扫描
	Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
			sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
	if (!componentScans.isEmpty() &&
			!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
		///循环所有的@ComponentScan注解注解的信息
		for (AnnotationAttributes componentScan : componentScans) {
			//立即扫描,内部最终将信息委托给ClassPathBeanDefinitionScanner进行包扫描,并执行过来过滤和条件筛选,非import类型会被直接注册BeanDefinition
			Set<BeanDefinitionHolder> 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注解,先是getImports(sourceClass)方法收集类上的所有@Import导入的类,递归收集(该注解可能是元注解)
		processImports方法循环处理逻辑如下:
		4.1 先判断如果候选组件是否ImportSelector接口子类,如果是:
				a.判断是DeferredImportSelector类,则收集导入类信息放入集合List<DeferredImportSelectorHolder> deferredImportSelectors中 --->ConfigurationClassParser类中的全局变量
				b.不是上述类,则调用ImportSelector接口方法获取导入的BeanNames,然后循环获取到对应类后进行封装,调用processImports方法递归解析
		4.2 再判断如果候选组件是否ImportBeanDefinitionRegistrar接口子类,收集导入类信息放入Map importBeanDefinitionRegistrars 中 -->> ConfigurationClass类中的全局变量
		4.3 其余是普通配置类放入MultiValueMap<String, AnnotationMetadata> imports中 -->> ConfigurationClass类中的全局变量
		4.4 普通配置类递归解析,再次调用processConfigurationClass方法解析
	processImports(configClass, sourceClass, getImports(sourceClass), true);

	//解析类上的@ImportResource导入资源文件,存放信息再Map<String, Class<? extends BeanDefinitionReader>> importedResources中 -->> ConfigurationClass类中的全局变量
	AnnotationAttributes importResource =
			AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
	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);
		}
	}

	//解析类获取所有类中含有@Bean注解的方法元数据,存储在ConfigurationClass.beanMethods中
	Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
	for (MethodMetadata methodMetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
	}

	//递归获取接口中含有@Bean注解的默认方法,解析收集方法元数据存放在ConfigurationClass.beanMethods中
	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);
			// Superclass found, return its annotation metadata and recurse
			return sourceClass.getSuperClass();
		}
	}

	//没有父类则说明解析完成
	return null;
}

解析过程总结:

  1. 先递归地处理任何成员(嵌套内部类)类,必须是一个配置类(full或者lite的模式)

  2. 解析类上的@PropertySources注解,用来导入properties文件信息,当前的environment应该是ConfigurableEnvironment接口实现类,否则会忽略该注解

  3. 解析类上的@ComponentScans注解,使用内部封装的componentScanParser解析器收集注解信息,最终将信息委托给ClassPathBeanDefinitionScanner进行包扫描。并执行过来过滤和条件筛选,非import类型会被直接注册BeanDefinition。

    3.1 包扫描默认从当前类下的包开始进行扫描,拿到包路径下的所有class类文件,只留下@component注解或该注解为元注解的标记的类。

    3.2 循环扫描到的类,先获取类的@Lazy @Primary @DependsOn @Role @Description注解信息存入BeanDefination中,将Bean定义信息和名称封装到BeanDefinitionHolder中,然后注册BeanDefinitionHolder到容器中

    3.3 获取到符合条件的类BeanDefinitionHolder组成的集合,循环集合,递归调用parse方法继续解析,解析完成的类缓存到ConfigurationClassParser.configurationClasses中。

  4. 解析类上的@Import注解,收集类上的所有@Import导入的类,递归收集(该注解可能是元注解),然后循环集合进行处理。

    4.1 先判断如果候选组件是否ImportSelector接口子类,如果是:

    a.判断是DeferredImportSelector类,则收集导入类信息放入集合List<DeferredImportSelectorHolder> deferredImportSelectors中 --->ConfigurationClassParser类中的全局变量
    b.不是上述类,则调用ImportSelector接口方法获取导入的BeanNames,然后循环获取到对应类后进行封装,调用processImports方法递归解析@Import注解
    

    4.2 再判断如果候选组件是否ImportBeanDefinitionRegistrar接口子类,收集导入类信息放入Map importBeanDefinitionRegistrars 中 -->> ConfigurationClass类中的全局变量

    4.3 其余是普通配置类放入MultiValueMap<String, AnnotationMetadata> imports中 -->> ConfigurationClass类中的全局变量

    4.4 普通配置类递归解析,再次调用processConfigurationClass方法解析

  5. 解析类上的@ImportResource导入资源文件,存放信息再Map<String, Class<? extends BeanDefinitionReader>> importedResources中 -->> ConfigurationClass类中的全局变量

  6. 解析类获取所有类中含有@Bean注解的方法元数据,存储在ConfigurationClass.beanMethods中。因为解析是先解析自己@Bean注解方法,再解析父类@Bean方法,所以这个成员变量中包含了所有@Bean注解的方法,但是子类的的是排在前面的,所以循环注册的时候先注册子类的,再注册父类的时候发现Bean名称被使用了,则会跳过,从而达到子类覆盖父类的效果。

  7. 获取接口中含有@Bean注解的默认方法,解析收集方法元数据存放在ConfigurationClass.beanMethods中

  8. 获取类的父类,重复以上步骤进行解析,没有父类子结束该类的解析。

  9. 以上类中解析过的配置类被封装到了ConfigurationClass实例中,该实例又被封装到ConfigurationClassParser的成员变量 Map configurationClasses中

上述整个解析过程解析的都是项目用户自己在项目下通过注解注入自定义的类,或者通过注解提前注入spring中定义的组件。

由Spring自己引导注入的spring自己的组件是通过processDeferredImportSelectors方法开启的,整个调用过程复杂且涉及很多递归调用。

loadBeanDefinitions方法加载BeanDefinition

//循环加载BeanDefinitions,执行各种条件判断逻辑
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
	TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
	//循环所有的配置类,注册BeanDefinition到容器
	for (ConfigurationClass configClass : configurationModel) {
		loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
	}
}
private void loadBeanDefinitionsForConfigurationClass(
		ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
	
	//判断是否需要跳过,执行@Conditional注解条件
	if (trackedConditionEvaluator.shouldSkip(configClass)) {
		String beanName = configClass.getBeanName();
		if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
			this.registry.removeBeanDefinition(beanName);
		}
		this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
		return;
	}
	
	//判断该类是否是@import注解导入的
	if (configClass.isImported()) {
		//从@import的配置类中注册BeanDefinition
		registerBeanDefinitionForImportedConfigurationClass(configClass);
	}
	
	//获取类及其父类中所有@Bean注解的方法(解析的时候收集的),注册BeanDefinition
	for (BeanMethod beanMethod : configClass.getBeanMethods()) {
		loadBeanDefinitionsForBeanMethod(beanMethod);
	}
	//从导入的资源导入BeanDefinition
	loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
	//从实现了ImportBeanDefinitionRegistrar接口的类中导入(import的时候解析了)
	loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
	ConfigurationClass configClass = beanMethod.getConfigurationClass();
	MethodMetadata metadata = beanMethod.getMetadata();
	String methodName = metadata.getMethodName();

	// 使用ConditionEvaluator.shouldSkip方法判断@Conditional注解条件进行处理
	if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
		//将需要跳过的类添加到Set集合中,供后续判断使用
		configClass.skippedBeanMethods.add(methodName);
		return;
	}
	//判断是否需要跳过的类
	if (configClass.skippedBeanMethods.contains(methodName)) {
		return;
	}

	AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
	Assert.state(bean != null, "No @Bean annotation attributes");

	// Consider name and any aliases
	List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
	String beanName = (!names.isEmpty() ? names.remove(0) : methodName);

	//注册别名
	for (String alias : names) {
		this.registry.registerAlias(beanName, alias);
	}

	//判断是否有被注册过:解析的时候先解析自己@Bean注解方法,再解析父类@Bean方法,会存在子类重写父类的方法,
	//因为存储时有序的,所以子类的@Bean注解的方法会先被注册,这里判断父类的方法时候会跳过注册父类方法
	if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
		if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
			throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
					beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +
					"' clashes with bean name for containing configuration class; please make those names unique!");
		}
		return;
	}
	
	//构造配置类的定义信息
	ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
	beanDef.setResource(configClass.getResource()); //设置类资源路径(全类名)
	beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
	
	//判断是静态方法还是实例方法
	if (metadata.isStatic()) {
		beanDef.setBeanClassName(configClass.getMetadata().getClassName());
		beanDef.setFactoryMethodName(methodName);
	}else {
		beanDef.setFactoryBeanName(configClass.getBeanName());
		beanDef.setUniqueFactoryMethodName(methodName);
	}
	beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
	beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
	
	//解析@Lazy @Primary @DependsOn @Role @Description注解信息放入beanDef中
	AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
	//设置注入模式(通过名称,或者类型,或者不注入)
	Autowire autowire = bean.getEnum("autowire");
	if (autowire.isAutowire()) {
		beanDef.setAutowireMode(autowire.value());
	}
	//设置初始化和销毁方法
	String initMethodName = bean.getString("initMethod");
	if (StringUtils.hasText(initMethodName)) {
		beanDef.setInitMethodName(initMethodName);
	}

	String destroyMethodName = bean.getString("destroyMethod");
	beanDef.setDestroyMethodName(destroyMethodName);

	//设置代理模式
	ScopedProxyMode proxyMode = ScopedProxyMode.NO;
	AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
	if (attributes != null) {
		beanDef.setScope(attributes.getString("value"));
		proxyMode = attributes.getEnum("proxyMode");
		if (proxyMode == ScopedProxyMode.DEFAULT) {
			proxyMode = ScopedProxyMode.NO;
		}
	}

	// Replace the original bean definition with the target one, if necessary
	BeanDefinition beanDefToRegister = beanDef;
	if (proxyMode != ScopedProxyMode.NO) {
		BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
				new BeanDefinitionHolder(beanDef, beanName), this.registry,
				proxyMode == ScopedProxyMode.TARGET_CLASS);
		beanDefToRegister = new ConfigurationClassBeanDefinition(
				(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
	}

	if (logger.isDebugEnabled()) {
		logger.debug(String.format("Registering bean definition for @Bean method %s.%s()",
				configClass.getMetadata().getClassName(), beanName));
	}
	//注册BeanDefinition
	this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
registerBeanDefinitionForImportedConfigurationClass
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
	AnnotationMetadata metadata = configClass.getMetadata();
	AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);

	ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
	configBeanDef.setScope(scopeMetadata.getScopeName());
	String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
	//解析@Lazy @Primary @DependsOn @Role @Description注解信息放入configBeanDef中
	AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);

	BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
	definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
	//注册BeanDefinition
	this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
	configClass.setBeanName(configBeanName);

	if (logger.isDebugEnabled()) {
		logger.debug(".....");
	}
}
loadBeanDefinitionsForBeanMethod
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
	ConfigurationClass configClass = beanMethod.getConfigurationClass();
	MethodMetadata metadata = beanMethod.getMetadata();
	String methodName = metadata.getMethodName();

	// 使用ConditionEvaluator.shouldSkip方法判断@Conditional注解条件进行处理
	if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
		//将需要跳过的类添加到Set集合中,供后续判断使用
		configClass.skippedBeanMethods.add(methodName);
		return;
	}
	//判断是否需要跳过的类
	if (configClass.skippedBeanMethods.contains(methodName)) {
		return;
	}

	AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
	Assert.state(bean != null, "No @Bean annotation attributes");

	// Consider name and any aliases
	List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
	String beanName = (!names.isEmpty() ? names.remove(0) : methodName);

	//注册别名
	for (String alias : names) {
		this.registry.registerAlias(beanName, alias);
	}

	//判断是否有被注册过:解析的时候先解析自己@Bean注解方法,再解析父类@Bean方法,会存在子类重写父类的方法,
	//因为存储时有序的,所以子类的@Bean注解的方法会先被注册,这里判断父类的方法时候会跳过注册父类方法
	if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
		if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
			throw new Exception();
		return;
	}
	
	//构造配置类的定义信息
	ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
	beanDef.setResource(configClass.getResource()); //设置类资源路径(全类名)
	beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
	
	//判断是静态方法还是实例方法
	if (metadata.isStatic()) {
		beanDef.setBeanClassName(configClass.getMetadata().getClassName());
		beanDef.setFactoryMethodName(methodName);
	}else {
		beanDef.setFactoryBeanName(configClass.getBeanName());
		beanDef.setUniqueFactoryMethodName(methodName);
	}
	beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
	beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
	
	//解析@Lazy @Primary @DependsOn @Role @Description注解信息放入beanDef中
	AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
	//设置注入模式(通过名称,或者类型,或者不注入)
	Autowire autowire = bean.getEnum("autowire");
	if (autowire.isAutowire()) {
		beanDef.setAutowireMode(autowire.value());
	}
	//设置初始化和销毁方法
	String initMethodName = bean.getString("initMethod");
	if (StringUtils.hasText(initMethodName)) {
		beanDef.setInitMethodName(initMethodName);
	}

	String destroyMethodName = bean.getString("destroyMethod");
	beanDef.setDestroyMethodName(destroyMethodName);

	//设置代理模式
	ScopedProxyMode proxyMode = ScopedProxyMode.NO;
	AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
	if (attributes != null) {
		beanDef.setScope(attributes.getString("value"));
		proxyMode = attributes.getEnum("proxyMode");
		if (proxyMode == ScopedProxyMode.DEFAULT) {
			proxyMode = ScopedProxyMode.NO;
		}
	}

	BeanDefinition beanDefToRegister = beanDef;
	if (proxyMode != ScopedProxyMode.NO) {
		BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
				new BeanDefinitionHolder(beanDef, beanName), this.registry,
				proxyMode == ScopedProxyMode.TARGET_CLASS);
		beanDefToRegister = new ConfigurationClassBeanDefinition(
				(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
	}

	if (logger.isDebugEnabled()) {
		logger.debug(String.format(".....",
				configClass.getMetadata().getClassName(), beanName));
	}
	//注册BeanDefinition
	this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}

整个解析过程中要记住的一点是:解析总是先从用户自定义的类中开始的,启动类就是入口。而启动类上的@SpringApplication注解就会导入一些类信息。另外启动类作为入口,该类上的所有注解都能够在解析过程中获取到。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Bean后置处理器BeanPostProcessor)是Spring框架中非常重要的一个功能,它允许我们在Bean实例化、依赖注入、初始化等步骤之前或之后,对Bean进行一些自定义操作。 Bean后置处理器是一个接口,它有两个方法: ```java Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; ``` 其中,`postProcessBeforeInitialization`方法在Bean初始化之前被调用,`postProcessAfterInitialization`方法在Bean初始化之后被调用。 我们可以通过实现Bean后置处理器接口,来自定义一些操作,比如: 1. 检查Bean是否符合一定的规范,如果不符合则抛出异常。 2. 在Bean初始化之前或之后,对Bean进行一些自定义操作,比如修改属性值、添加新的属性等。 3. 在Bean销毁之前或之后,做一些清理工作,比如关闭连接、释放资源等。 下面是一个简单的例子,演示如何使用Bean后置处理器,在Bean初始化之前输出一条日志: ```java public class MyBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("Before Initialization : " + beanName); return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("After Initialization : " + beanName); return bean; } } ``` 在Spring配置文件中,我们需要将这个Bean后置处理器注册到容器中,如下所示: ```xml <bean class="com.example.MyBeanPostProcessor"/> ``` 这样,每次容器创建一个Bean实例时,都会调用我们自定义的Bean后置处理器,执行自定义操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值