springboot-spring源码系列(六)

675 阅读11分钟

上篇文章中遗留了三个重要方法

1.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
2.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
3.DefaultListableBeanFactory.getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit)

1.getBeanNamesForType()完成了beanDefinition的查找

//记一下传过来的参数值 xxx.class  true  false
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
		/**
         * 三个判断条件
         * 1. !isConfigurationFrozen()返回beanFactory的configurationFrozen属性默认为false
         * private volatile boolean configurationFrozen = false;
         * 2. 传递过来type是否为null
         * 3. 传递过来的allowEagerInit是否为false
         */
		if (!isConfigurationFrozen() || type == null || !allowEagerInit) {	
        	//因为第一个条件默认为true所以一定会执行
			return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
		}
		Map<Class<?>, String[]> cache =
				(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
		String[] resolvedBeanNames = cache.get(type);
		if (resolvedBeanNames != null) {
			return resolvedBeanNames;
		}
		resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
		if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
			cache.put(type, resolvedBeanNames);
		}
		return resolvedBeanNames;
	}
	
//单纯的new了一个对象封装了type类型
public static ResolvableType forRawClass(@Nullable Class<?> clazz) {
		return new ResolvableType(clazz) {	
			@Override
			public ResolvableType[] getGenerics() {
				return EMPTY_TYPES_ARRAY;
			}
			@Override
			public boolean isAssignableFrom(Class<?> other) {
				return (clazz == null || ClassUtils.isAssignable(clazz, other));
			}
			@Override
			public boolean isAssignableFrom(ResolvableType other) {
				Class<?> otherClass = other.getRawClass();
				return (otherClass != null && (clazz == null || ClassUtils.isAssignable(clazz, otherClass)));
			}
		};
	}
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
		//创建一个List集合封装匹配当前类型的beanName集合
		List<String> result = new ArrayList<>();

		//循环此时beanDefinitionNames中的所有key拿到全限定类名
		for (String beanName : this.beanDefinitionNames) {
			//先判断本次循环的beanName是否存在于aliasMap
            //return this.aliasMap.containsKey(name);
			if (!isAlias(beanName)) {
				try {
                	/**
                     * RootBeanDefinition:通常用在bean的实例化阶段,为了方便实例化操作,提供了大量的缓存字段,方便重复实例化时减少工作量。
                     * 他会先尝试从mergedBeanDefinitions中拿到key为beanName的beanDefinition
                     * mergedBeanDefinitions:存放合成的beanDefinition,至于合成怎么理解,通过xml的方式指定了bean的父bean <bean parent="xxx"></bean>
                     * 找不到的话就会从beanDefinitionMap中找,然后返回beanDefinition
                     */
					RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
					/** 三个大判断
             		 * 1.private boolean abstractFlag = false;默认为true
                     * 2.只要有一个为true即可,mbd.hasBeanClass()一定为true
                     * 3.!containsSingleton(factoryBeanName)默认为false,最终为true
                     */
					if (!mbd.isAbstract() && (allowEagerInit ||
							((mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading())) &&
									!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
						// 判断是否是一个FactoryBean,最简单的理解就是是否实现了FactoryBean这个接口
						boolean isFactoryBean = isFactoryBean(beanName, mbd);					
                        //默认为null
						BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                        /**
                         * 这么复杂的判断,可以看到他是3个&&符号,而每一个又嵌套了||符号,
                         * 直接看重点 isTypeMatch(beanName, type);
                         * type封装了需要查找的beanDefinition的类型
                         * 这个方法没什么意思有兴趣的同学自己看,不建议看!就是通过beanName找到beanDefinition判断是否和指定类型匹配
                         */
						boolean matchFound =
								(allowEagerInit || !isFactoryBean ||
										(dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
										(includeNonSingletons ||
												(dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
										isTypeMatch(beanName, type);
                       //如果是一个FactoryBean,就在他的beanName的前面加上一个‘&’
						if (!matchFound && isFactoryBean) {
							beanName = FACTORY_BEAN_PREFIX + beanName;
                            //重新判断matchFound
							matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
						}
                        //如果类型匹配就把beanName添加进result集合
						if (matchFound) {
							result.add(beanName);
						}
					}
				} catch (CannotLoadBeanClassException ex) {
					if (allowEagerInit) {
						throw ex;
					}			
					if (this.logger.isDebugEnabled()) {
						this.logger.debug("Ignoring bean class loading failure for bean '" + beanName + "'", ex);
					}
					onSuppressedException(ex);
				} catch (BeanDefinitionStoreException ex) {
					if (allowEagerInit) {
						throw ex;
					}
					// Probably contains a placeholder: let's ignore it for type matching purposes.
					if (this.logger.isDebugEnabled()) {
						this.logger.debug("Ignoring unresolvable metadata in bean definition '" + beanName + "'", ex);
					}
					onSuppressedException(ex);
				}
			}
		}

  	//循环manualSingletonNames集合,beanFactory的初始化过程中添加了3个beanName
  	for (String beanName : this.manualSingletonNames) {
  		try {
  			// 判断是否为FactoryBean,默认都不是
  			if (isFactoryBean(beanName)) {
  				if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
  					result.add(beanName);
  					continue;
  				}
  				beanName = FACTORY_BEAN_PREFIX + beanName;
  			}
  			//判断是否原始bean实例,有兴趣的自己看,默认都不是
  			if (isTypeMatch(beanName, type)) {
  				result.add(beanName);
  			}
  		} catch (NoSuchBeanDefinitionException ex) {
  			if (logger.isDebugEnabled()) {
  				logger.debug("Failed to check manually registered singleton with name '" + beanName + "'", ex);
  			}
  		}
  	}
  	//
  	return StringUtils.toStringArray(result);
  }

2.postProcessBeanDefinitionRegistry()太重要了,一句话没法总结

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		/**
		 * 根据内存地址,生成唯一标识 ,用来验证重复处理
         * 每次创建Context都会产生一个新的registryId,
         * 只要不重新创建,返回的值都是同一个
         * 也就是说当前方法只会执行一次
		 */
		int registryId = System.identityHashCode(registry);
		if (this.registriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
		}
		if (this.factoriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + registry);
		}
		this.registriesPostProcessed.add(registryId);
		processConfigBeanDefinitions(registry);
	}
//解析配置类
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		//创建List集合封装所有注解类的beanDefinition
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
        //String集合保存了所有beanDefinition的beanName
		String[] candidateNames = registry.getBeanDefinitionNames();

		/**
		 * 循环所有candidateNames
		 */
		for (String beanName : candidateNames) {
        	//根据beanName从beanDefinitionMap中拿到beanDefinition
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			//判断当前的 beanDefinition 是不是一个配置类
			// FullConfiguration 全配置类
			// LiteConfiguration 半配置类
            // 至于这两种配置类有什么区别有什么用,下文中都会详解
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				// 如果他是一个配置类那么就会打印语句 该beanDefinition已经是一个配置类
				//正常情况下他是不会走的,因为现在spring并不知道谁是配置类 都是beanDefinition
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
			//该方法就是判断那个是配置类,并且判断到底是全配置类、半配置类、不是配置类
            //所有的beanDefinition都会进行判断,如果是配置类则创建BeanDefinitionHolder来封装beanDefinition
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}
//看spring是如何判断类是否是配置类
public static boolean  checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
			//拿到类的全限定类名
			String className = beanDef.getBeanClassName();
			//如果className为空直接返回
			if (className == null || beanDef.getFactoryMethodName() != null) {
				return false;
			}
	
			//封装类的元数据(所有注解)
			AnnotationMetadata metadata;
			/**
             * 先判断该beanDefinition是否实现了AnnotatedBeanDefinition
             *  	spring中的RootBeanDefinition代表spring内置的类
             *		AnnotatedBeanDefinition代表通过reader读取进来的
             *  	ScannerBeanDefinition代表通过Scanner扫描进来的
             * 如果第一个判断满足,则当前的beanDefinition强转成AnnotatedBeanDefinition,比较他的ClassName是否一致,有可能会出现FactoryBean这种情况,正常情况下都一致 
             */
			if (beanDef instanceof AnnotatedBeanDefinition &&
					className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
                 //拿到配置类上的所有注解信息
				metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();

			//所有beanDefinition都实现了AbstractBeanDefinition,再判断是否有beanClass
			} else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
            	//拿到所有注解信息
				Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
				metadata = new StandardAnnotationMetadata(beanClass, true);
			} else {
				try {
					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);
					}
					return false;
				}
			}
			/**
			 * 判断他是不是一个全配置类
			 * 很简单 直接判断她有没有 @Configuration 这个注解 如果有就给当前beanDefinition添加一个key-value用来表示是全配置类
			 */

			if (isFullConfigurationCandidate(metadata)) {
				beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
			}
			/**
			 * 判断是不是半配置类,如果当前配置类有下面这四个注解中的一个或者有加了@bean的方法则证明是半配置类
			 *  @Component.class.
			 * 	@omponentScan.class.
			 * 	@Import.class.
			 * 	@ImportResource.class.
			 *  同样添加一个key-value
			 */
			else if (isLiteConfigurationCandidate(metadata)) {
				beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
			}
			//如果都不满足,直接返回false
			else {
				return false;
			}
	
			//判断是否有@Order注解,如果有多个配置类则会根据@Order注解来决定执行顺序
			Integer order = getOrder(metadata);
			if (order != null) {
                //同样添加一个key-value
				beanDef.setAttribute(ORDER_ATTRIBUTE, order);
			}
	
			return true;
		}
		/**
		 * 如果没有注解类,直接返回
		 */
		if (configCandidates.isEmpty()) {
			return;
		}

		/**
		 * 如果有多个配置类,并且都实现了Order接口,则按升序排序
         * 有兴趣自己去看
		 */
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
		});
		/**
         *  拿到beanFactory然后getSingleton()就是从单例池拿是否有自定义的实现了internalConfigurationBeanNameGenerator接口的类
         *  如果不为空则更改componentScan和importBean的解析方式,
		 *  如果为空默认使用spring自己的解析器
		 */
		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;
				}
			}
		}
		//ConfigurationClassPostProcessor的environment如果为null则new StandardEnvironment()
        //不可能为null,因为手动注册进beanDefinitionMap的时候给他设置了Context的enviroment
		if (this.environment == null) {
			this.environment = new StandardEnvironment();
		}
		/**
		 * 初始化一个ConfigurationClassParser用来解析配置类,把ConfigurationClassPostProcessor的部分属性添加给他
		 */
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		// 对扫描出来的配置类进行去重操作
		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		// 创建一个set集合来缓存已经解析完成的配置类
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		/**
		 * 循环解析,还是因为配置类解析完成后回把扫描到的类转变成beanDefiniton添加进beanDefinitionMap中
         * 防止这些beanDefinition还是配置类
		 */
		do {
			//解析所有配置类
			parser.parse(candidates);
public void parse(Set<BeanDefinitionHolder> configCandidates) {
	//省略的代码不重要,直接看重点	
	parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
	}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
		processConfigurationClass(new ConfigurationClass(metadata, beanName));
	}
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
		//判断是否需要解析,@ConditionOnBean注解  springboot大量使用
		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);
			}
		}
		//单纯进行了数据转换 多了一些属性,底层依然还是appConfig配置类
		SourceClass sourceClass = asSourceClass(configClass);
		do {
			//真正解析一个类
			sourceClass = doProcessConfigurationClass(configClass, sourceClass);
		}
		//返回的值不为空,表示解析的配置类还有父配置类,继续解析
		while (sourceClass != null);
		//添加到到一个临时map中
		this.configurationClasses.put(configClass, configClass);
	}
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
			throws IOException {            
		//递归处理内部类99%的情况不会写内部类
		processMemberClasses(configClass, sourceClass);
		/**
		 * 拿到配置类上的@PropertySources注解
         * @PropertySources注解是吧properties配置文件中的值存储到Spring的Environment中,
         * Environment接口提供方法去读取配置文件中的值,参数是properties文件中定义的key值。
         * 有兴趣的同学自己看
		 */
		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("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
						"]. Reason: Environment must implement ConfigurableEnvironment");
			}
		}
		/**
         * 拿到配置类上的@ComponentScan注解中的信息,封装成AnnotationAttributes对象保存进集合中
         * 并且设置一些默认属性
         * 为什么用集合因为 ComponentScan[] value() 
         */

		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
          //如果不为空并且不跳过就对@ComponentScan进行解析
		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			// 循环处理componentScans
			for (AnnotationAttributes componentScan : componentScans) {
				/**
				 * 对包路径下的类进行解析,然后变成beanDefinition注入beanDefinitionMap中 
                 * scannedBeanDefinitions保存了所有成功注入的类的BeanDefinitionHolder
				 */
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
	   //创建一个扫描器,扫描包转换成beanDefinition
       //这也证明了在构造方法中的那个扫描器只是用来通过api扫描的
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
				componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
         。。。。。。。
         //中间的方法有兴趣自己去看,主要就是对ComponentScan的其他属性进行解析和添加过滤器
         。。。。。。。
        //创建set集合保存包路径
        Set<String> basePackages = new LinkedHashSet<>();
        //拿到@ComponentScan注解上的basePackages属性的值
		String[] basePackagesArray = componentScan.getStringArray("basePackages");
        //主要就是对包路径进行解析校验操作,比如说去掉空格、解析转义符等等
		for (String pkg : basePackagesArray) {
			String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
					ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
			basePackages.addAll(Arrays.asList(tokenized));
		} 
        //调用扫描器执行扫描包路径操作
        return scanner.doScan(StringUtils.toStringArray(basePackages));
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		//检验basePackages是否为空
		Assert.notEmpty(basePackages, "At least one base package must be specified");
        //保存扫描出来的所有类的beanDefinition
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
		for (String basePackage : basePackages) {
			//根据basePackage加载路径下所有java文件,并扫描出所有bean组件,并且转换成beanDefinition
            //简单分析一下如何扫描出来的
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
			//对路径进行解析: "classpath:xxx/xxx/**/*.class"
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			//拿到路径下的所有class文件,使用了asm技术,有兴趣的同学可以自己去了解

			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
			boolean traceEnabled = logger.isTraceEnabled();
			boolean debugEnabled = logger.isDebugEnabled();
			//对每个文件进行循环判断
			for (Resource resource : resources) {
            	//默认为true
				if (resource.isReadable()) {
					try {
						//拿到每个class文件上的注解
						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
						//对注解进行解析有没有@Componet注解,避免不必要的类被创建
						if (isCandidateComponent(metadataReader)) {						
						   //创建了ScannedGenericBeanDefinition 类型的bd
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                            //把绝对路径设置给beanDefinition
							sbd.setResource(resource);
							sbd.setSource(resource);
							//接口、抽象类、有@Lookup注解都不会被创建
							if (isCandidateComponent(sbd)) {
								if (debugEnabled) {
									logger.debug("Identified candidate component class: " + resource);
								}
								//存到set集合中去
								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 (Throwable ex) {
						throw new BeanDefinitionStoreException(
								"Failed to read candidate component class: " + resource, ex);
					}
				}
				else {
					if (traceEnabled) {
						logger.trace("Ignored because not readable: " + resource);
					}
				}
			}
		}

		//最后把扫描出来的所有beanDefinition集合返回
		return candidates;
	}
			//遍历扫描出来的beanDefinition
			for (BeanDefinition candidate : candidates) {
				//解析作用域Scope
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				//利用beanNameGenerator生成beanName,类名首字母小写
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				/**
				 * 一定会执行,因为ScannedGenericBeanDefinition是 AbstractBeanDefinition的子类
				 * 此时他的注解信息全都是默认的
				 * 但是配置类可以对扫描出来的bd进行默认注解设置
				 * 此时就对bd进行默认修改
				 */
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				/**
				 *  此时beanDefinition自己的注解信息放在beanDefinition中的metadata中
				 *  从metadata中解析到beanDefinition结构中,主要是处理Lazy, primary DependsOn, Role ,Description这五个注解
				 */
				if (candidate instanceof AnnotatedBeanDefinition) {
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				//检查当前bean是否已经注册,不存在则注册
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					/**
					 * 	把beanDefinition注册到beanDefinitionMap集合中,并没有直接放到singeltonObjects中
 					 */
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}
				// 遍历扫描出的bean定义是否是配置类bean
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					/**
					 *   如果扫描出的bean定义是配置类(全配置类或者半配置类),则继续调用parse方法,
					 *   也就说大部分都会在去执行一遍,因为都加了@component/@service...等注解
					 *   内部再次调用doProcessConfigurationClas(),递归解析
					 */
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(
							holder.getBeanDefinition(), this.metadataReaderFactory)) {
						parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}		
		/**
		 * 上面的代码完成对@ComponentScan注解的解析,而且解析出来直接注册进beanDefinitionMap中
		 */

spring提供的两个扩展接口

importSelector

importBeanDefinitionRegister

		/**
		 * 注意如果你是通过@componentScan的方式扫描注入的实现了importSelector和importBeanDefinitionRegister
         * 全部都是一个普通的bean,也就是说不会去执行实现的方法
		 * 处理@import的三种情况
		 *  1. importSelector 执行方法,结果保存在deferredImportSelectors集合中
		 *  2. 普通类 把所有类保存在imports集合中
		 *  3. importBeanDefinitionRegister  不执行方法,保存在importBeanDefinitionRegistrars集合中
		 *    getImports(sourceClass) 拿到当前类上的@import注解值,也会查找子注解上的所有@import注解
         *  该方法仅仅只是把类扫描出来保存在集合中,并没有转换成beanDefinition
		 */
		processImports(configClass, sourceClass, getImports(sourceClass), true);

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
								Collection<SourceClass> importCandidates, boolean checkForCircularImports) throws IOException {

		//如果没有import注解直接返回
		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		} else {
			//
			this.importStack.push(configClass);
			try {
				//循环解析所有@impor
				for (SourceClass candidate : importCandidates) {
					//判断当前这个类是否实现了 ImportSelector 接口
					if (candidate.isAssignable(ImportSelector.class)) {
						//利用反射,返回该类唯一Class实例对象
						Class<?> candidateClass = candidate.loadClass();
						 //利用class实例通过构造方法反射得到对象
						ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
						//如果该类实现了spring中的Aware接口,则添加到一个集合中后续执行
						ParserStrategyUtils.invokeAwareMethods(
								selector, this.environment, this.resourceLoader, this.registry);
						//如果他实现的是 DeferredImportSelector接口 则添加到一个List集合 以后进行执行
						if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
							this.deferredImportSelectors.add(
									new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
						} else {
							//执行selector.selectImports()方法拿到真正需要被注入的类的全限定名放入数组中
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							 //类型转换 数组--->集合
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
							/**
							 * 递归解析集合中的所有类
							 * 如果 importSourceClasses 中为空直接返回,否则解析 selector.selectImports() 中的类
							 */
							processImports(configClass, currentSourceClass, importSourceClasses, false);
						}
					//判断该类是否实现了 ImportBeanDefinitionRegistrar 接口
					} else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
						ParserStrategyUtils.invokeAwareMethods(
								registrar, this.environment, this.resourceLoader, this.registry);
						//此时并没有执行他的registerBeanDefinitions方法,仅仅只是把当前类保存到集合中
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
				   //如果它是一个普通类
					} else {
                    	//注册到imports集合中,此时并没有转换成beanDefinition
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						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();
			}
		}
	}
		//拿到所有@ImportResource注解,有兴趣自己看
		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注解的方法,直接通过元数据信息就可以拿到
		Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
		for (MethodMetadata methodMetadata : beanMethods) {
			//将解析出的所有@Bean注解方法添加到beanMethods集合中,也仅仅只是保存没有转换成beanDefinition
			configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
		}
		/**
		 * 处理配置类的接口中(也就是当前正在解析的类)所有添加@Bean注解的方法,
		 * 内部通过遍历所有接口,解析得到@Bean注解方法,并添加到configClass配置类信息中
		 */
		processInterfaces(configClass, sourceClass);
		// 如果有父类,则返回父类,一定会执行,因为所有类都有父类(Object)
		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();
			}
		}
        //如果是非配置类直接返回null
		return null;
	}

- 不容易,终于绕回来了,如果你还知道下面的代码是在那个方法中,证明你有天赋!

			//主要校验扫描出来的有@Component类是否有final修饰符(CGLIB代理是生成一个子类,因此原先的类不能使用final修饰)
			parser.validate();
			//存放所有扫描出来有@component注解的类
			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			//移除掉已经解析过的配置类
			configClasses.removeAll(alreadyParsed);
			//如果读取器为空则创建一个单例模式--懒汉式,用来把对象转换为bd
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			/**
			 * 这里值得注意的是扫描出来的bean当中可能包含了特殊类
			 * 比如importBeanDefinitionRegister 也会在这个方法中处理	
			 * configClasses主要包含的是import的普通类、importSector中方法返回的普通类、@bean方法、@importResources
             * 每个集合对应什么,上文中都说明了
			 */

			this.reader.loadBeanDefinitions(configClasses);
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
		TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
		for (ConfigurationClass configClass : configurationModel) {
			loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
		}
	}
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass,
			TrackedConditionEvaluator trackedConditionEvaluator) {

		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注入的类注册为beanDefinition 放入map集合中
		if (configClass.isImported()) {
			registerBeanDefinitionForImportedConfigurationClass(configClass);
		}
		//将@Bean方法注册为beanDefinition 放入map集合中
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}
		//将configClass中通过ImportResource指定的资源注册为bean
		loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
		//执行configClass中实现ImportedBeanDefinitionRegistrar接口的方法,然后把该类注册进beanDefinitionMap中
		loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
	}
			//将已经执行过的配置类添加进执行完毕的集合中
			alreadyParsed.addAll(configClasses);
			//清空candidates集合,表示已经全部解析完毕
			candidates.clear();
			//再次获取容器中bean定义数量 如果大于之前获取的bean定义数量,则说明有新的bean注册到容器中,在判断一遍此时beanDefinitionMap中是否有没执行的配置类
			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);
						//新注册的bean如果也是@Configuration配置类,则添加到数据,等待解析
						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
							candidates.add(new BeanDefinitionHolder(bd, candidateName));
						}
					}
				}
				candidateNames = newCandidateNames;
			}
		}
		//全部解析完成则跳出循环
		while (!candidates.isEmpty());
        //将ImportRegistry注册为bean以支持importware@Configuration类
		if (sbr != null) {
			if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
				sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
			}
		}
		//在外部提供的MetadataReaderFactory中清除缓存;这是不可操作的
		//因为它将被ApplicationContext清除。
		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}

OK,这个方法我觉得完全讲透了,最后贴一下自己的测试类

只有通过@import的方式才会执行方法,不然仅仅只是一个普通类,这是spring提供的扩展点之一。@EnableXxxx 这种注解都是利用了这种特性

3.postProcessBeanFactory()最后一个方法,对配置类进行增强

//直接看重点,至于怎么进来的上篇文章中进行了解析
ConfigurationClassPostProcessor.postProcessBeanFactory();

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		//生成唯一id防止重复执行
		int factoryId = System.identityHashCode(beanFactory);
		if (this.factoriesPostProcessed.contains(factoryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + beanFactory);
		}
		this.factoriesPostProcessed.add(factoryId);
		if (!this.registriesPostProcessed.contains(factoryId)) {
			processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
		}
		//进行cglib代理
		enhanceConfigurationClasses(beanFactory)
		//为beanFactory添加了第三个后置处理器
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
	}
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
		//创建Map保存需要进行CGLIB代理的beanDefinition
		Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
		//拿到此时beanDefinitionNames中所有的beanName
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			//通过key拿到map中的beanDefinition
			BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
	    	//判断它是否是全配置类,在解析的过程中给配置类设置了 CONFIGURATION_CLASS_ATTRIBUTE  = full
            //spring中全配置类和半配置类的区别就在于是否会进行cglib代理
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
				//他是否是一个基本的beanDefinition
				if (!(beanDef instanceof AbstractBeanDefinition)) {
					throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
							beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
					//beanFactory中的singletonObjects是否存在该bean
				} else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
					logger.warn("Cannot enhance @Configuration bean definition '" + beanName +
							"' since its singleton instance has been created too early. The typical cause " +
							"is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
							"return type: Consider declaring such methods as 'static'.");
				}
				//添加进需要进行cglib代理的集合中
				configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
			}
		}
		//如果是空直接返回去
		if (configBeanDefs.isEmpty()) {
			return;
		}
		//创建一个cglib生成器
		ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
		//拿到每一个beanDefinition
		for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
			AbstractBeanDefinition beanDef = entry.getValue();
			//设置属性 PRESERVE_TARGET_CLASS_ATTRIBUTE = true表示进行过cglib
			beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
			try {
				//通过反射得到本次循环中的beanDefinition对应类的Class实例
				Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
				if (configClass != null) {
					/**
                     * 进行cglib动态代理,返回一个CGLIB的实例
                     * 为什么要进行CGLIB代理?
                     * 在bean的实例化过程中,会通过配置类中的@bean方法进行创建
                     * 但是如果@bean方法中引用了配置类中的其他@bean方法,就会创建无用对象,而且违背了spring的设立理念
                     * spring为了解决这种问题,就想到了通过代理对类进行增强,多进行一次判断
                     */
					Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);

public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
		//如果该类的父接口是EnhancedConfiguration.class代表已经进行过cglib代理
		if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
        	return configClass;
        }
        //通过cglib生成器创建Class对象,重点就是分析CGLIB做了什么增强
        Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
		return enhancedClass;
	}
private Enhancer newEnhancer(Class<?> superclass, @Nullable ClassLoader classLoader) {
		//创建一个默认的增强器
		Enhancer enhancer = new Enhancer();
		//设置父类为就是原始的类
		enhancer.setSuperclass(superclass);
		//设置实现的接口EnhancedConfiguration.class并且EnhancedConfiguration接口实现了BeanFactoryAware接口
        //所以该代理类有一个实现方法setBeanFactory()
		enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
        //设置useFactory属性为false
		enhancer.setUseFactory(false);
        //设置代理类的名字后缀为BySpringCGLIB
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		/**
		 * 添加了一个生成策略,就是为我们代理的类添加了一个属性 BeanFactory $$BeanFactory = null
         * 因为代理类有一个setBeanFactory()方法,所以这个属性一定会赋值
		 * 好处就是我们不用添加任何一个方法,只需要通过这个属性中的方法就能拿到beanFactory做各种操作
		 */
		enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
		/**
		 * 添加回调过滤器,也就是对每个方法进行增强,一共添加了两个增强类
		 *    1.BeanMethodInterceptor(),
		 *     	  判断所有方法是否有@bean注解如果有就进行了增强
		 *    2.BeanFactoryAwareMethodInterceptor(),
		 *     	  判断 $$beanFactory这个属性是否有实例,有就直接返回,没有去创建
		 */
		enhancer.setCallbackFilter(CALLBACK_FILTER);
		enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
		return enhancer;
	} 
//就贴一下重点代码
private static class
	BeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
		public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
					MethodProxy cglibMethodProxy) throws Throwable {
			//首先通过反射从增强的 Configuration 注解类中获取 beanFactory
			ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
			//beanName就是全限定类名+方法名也可以通过@bean("xxx")指定
			String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
		
			/**
			 *	判断当前执行的方法是否是第一次执行,
			 *
			 *  public xx setXX(){return new xx()};
			 *  public xx2 setXX2(){ setXX() ;  return new xx2()};
			 *  public xx3 setXX3(){return new xx3()};
			 *  上面举得例子:名字是不同的  setXX  setXX2
			 *  如果是第一次执行那么他的代理方法的名字 和 原来创建对象方法的名字是相同的
			 *  如果不是第一次,那么他的代理方法的名字 和 原来创建对象方法的名字是不同的
			 *  那么这个返回值就是 false.
			 */
			if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
				//如果是第一次。那么直接通过反射执行原方法
				return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
			}		
			//不是第一次,则直接从singletonObjects拿
			return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
		}
        
private static class BeanFactoryAwareMethodInterceptor implements MethodInterceptor, ConditionalCallback {

		@Override
		@Nullable
		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			Field field = ReflectionUtils.findField(obj.getClass(), BEAN_FACTORY_FIELD);
			Assert.state(field != null, "Unable to find generated BeanFactory field");
			field.set(obj, args[0]);
			//实际的(非CGLIB)超类是否实现BeanFactoryAware?
			//如果是,则调用其setBeanFactory()方法。如果没有,就退出。
			if (BeanFactoryAware.class.isAssignableFrom(ClassUtils.getUserClass(obj.getClass().getSuperclass()))) {
				return proxy.invokeSuper(obj, args);
			}
			return null;
		}  
					if (configClass != enhancedClass) {
						if (logger.isDebugEnabled()) {
							logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
									"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
						}
						//对配置类的beanDefinition的beanClass属性进行替换,替换成代理之后的Class对象
						beanDef.setBeanClass(enhancedClass);
					}
				}
			} catch (Throwable ex) {
				throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
			}
		}
	}

到这里refresh()的invokeBeanFactoryPostProcessors(beanFactory)基本讲透了,剩下的重点就是finishBeanFactoryInitialization(beanFactory);方法