Spring源码解析系列五:Spring扫描组件之ConfigurationClassPostProcessor

523 阅读15分钟

1.准备测试类

public class Test01 {
	public static void main(String[] args) {
		//这个构造方法会把Spring所有的环境都准备好
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
	}
}

配置类

@ComponentScan("com.v1")
@Component
@Configuration
public class SpringConfiguration {

}

PersonService类

@Component
public class PersonService {
}

2.点击`AnnotationConfigApplicationContext`

	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//这个类有父类,所以会先初始化父类的构造方法,接着初始化自己的构造方法
		//调用无参构造方法进行初始化一个读取器和扫描仪
		this();
		//把配置类加载进 DefaultListableBeanFactory 的map集合中
		//配置类可以一次性传多个,这个方法执行后,只是把配置类加载进了 DefaultListAbleBeanFactory的map集合中
		//还没有扫描其他的的加了组件的类
		register(annotatedClasses);
		//实例化所有被加了组件的对象
		refresh();
	}

3.点击`refresh()`

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
			//这个方法不是重点,可以暂时认为他不干任何事情
			prepareRefresh();

			//获取工厂对象 ,本质是DefaultListableBeanFactory对象
			//其实读取xml文件变成beanDefinition,也是在这里面完成的
			//所以这里面的功能和register(annotatedClasses);功能很像
			//一个是是从xml文件中读取配置信息,一个是通过类的注解读取信息
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//为BeanFactory配置类加载器、后置处理器等等
			//这个方法比较重要
			prepareBeanFactory(beanFactory);

			try {
				//这个方法是空方法,Spring还没有做任何事情
				//猜测以后Spring会使用这个方法
				postProcessBeanFactory(beanFactory);


				//在这个方法中开始扫描被组件标记的类, 把类的信息
				// 封装成一个GenericBeanDefinition存储在map集合中
				//这个是非常重要的一个方法
				invokeBeanFactoryPostProcessors(beanFactory);
				
				//省略剩余代码...
				
				}

4.点击 `invokeBeanFactoryPostProcessors(beanFactory)`

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {

//重点方法,执行beanFactoryPostProcessors后置处理器
//注意这里 getBeanFactoryPostProcessors() 是获取不到用户自己的BeanFactoryPostProcessor的实现类的 ,因为这个时候还没有开始扫描包
//需要自己手动赋值给这个大容器对象,也就是AnnotationConfigApplicationContext
//ac.addBeanFactoryPostProcessor(....);
//getBeanFactoryPostProcessors()可以获取到用户自定义的作用类,前提是手动创建,传进来的	
    
 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

5.点击 `invokeBeanFactoryPostProcessors`

	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

// 1. 处理用户自己的后置处理器,处理的是用户自己创建对象传的ac.addBeanFactoryPostProcessor()
//如果你想在扫描所有包之前就执行你的后置处理器的话,可以首先把的后置处理器注册给Spring
//就是通过 ac.addBeanFactoryPostProcessor(对象) 这样子注解
		Set<String> processedBeans = new HashSet<>();
           //判断当前的beanFactory是否是BeanDefinitionRegistry
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//定义两个集合BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor
//bdrpp 增强了一个功能 ,也就是说他们的功能是不一样的,所以需要定义两个集合
//regularPostProcessors 存储用户自己传进来的BeanFactoryPostProcessor的实现类
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors存储用户自己传进来的BeanDefinitionRegistryPostProcessor的实现类
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//判断的bean是否实现了BeanDefinitionRegistryPostProcessor
//如果bean实现了BeanDefinitionRegistryPostProcessor这个接口,可以获取到整个容器对象,也就是registry对象
//而实现BeanFactoryPostProcessor,只能获取 到bean工厂 对象
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					//如果当前的bean实现的是BeanDefinitionRegistryPostProcessor
					//添加进registryProcessors集合
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					//如果只是实现了beanFactoryPostProcessors添加进regularPostProcessors集合
					regularPostProcessors.add(postProcessor);
				}
			}
  //其实前面都不是重点,基本不会有人自己手动创建对象添加给Spring容器的,以下才是重点

//2.处理Spring内部的后置处理器,Spring内部的处理器 ,就只有一个类实现BeanDefinitionRegistryPostProcessor
//currentRegistryProcessors存放Spring内部类实现了BeanDefinitionRegistryPostProcessor接口的类
//ConfigurationClassPostProcessor 这个就是实现类 BeanDefinitionRegistryPostProcessor
//ConfigurationClassPostProcessor就是Spring内部的后置处理器
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

//从beanFactory工厂中寻找判断哪个类型实现了BeanDefinitionRegistryPostProcessor接口,拿出该类的beanName
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			//遍历所有的后置处理器beanName ,通过beanName从bean工厂中把对象取出来
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					//把名称存储到processedBeans集合中
					processedBeans.add(ppName);
				}
			}
			//排序,不是重点 ,内部只有一个
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			//合并list ,把用户之间定义和Spring之间内部的合并在一个集合中
            //合并基本是没有用的,一般用户不会自己手动创建对象注册进Spring容器
			registryProcessors.addAll(currentRegistryProcessors);

             //执行当前的后置处理器,其实到这里currentRegistryProcessors只有一个处理器,
			//主要处理扫描配置类对应包下的类
            //点击这个
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			//清空集合
			currentRegistryProcessors.clear();
		  //剩余代码省略....其实下面的代码也有一部分很重要的,以后再聊
        
			}

6.点击 `invokeBeanDefinitionRegistryPostProcessors`方法

该方法把 currentRegistryProcessors集合和全局对象registry传入

currentRegistryProcessors其实该集合仅仅是存储到了一个类 ConfigurationClassPostProcessor

	private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
         //遍历集合,其实只有一个类,而这个类正是ConfigurationClassPostProcessor
		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
            //开始执行 ConfigurationClassPostProcessor 的方法
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
	}

7.点击`postProcessBeanDefinitionRegistry`

该方法其实是 BeanDefinitionRegistryPostProcessor接口继承了 BeanFactoryPostProcessor扩展的方法

@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		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);
	}

8.点击 `processConfigBeanDefinitions`

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		//所有被加了注解的bean,都将存储在configCandidates这个集合中
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		//获取工厂中所有的beanName
		String[] candidateNames = registry.getBeanDefinitionNames();
		//遍历所有的beanName
			for (String beanName : candidateNames) {
			//通过beanName获取到对象
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
		//判断该对象时候被处理过了,ConfigurationClass属性为full或者是lite,则意味着已经处理过了
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
			//循环中判断当前的对象是否用@Component,@ComponentScan等类型的注解
			//如果当前的bean(其实就是配置类)有带@configuration 则属性值添加为 full
			//如果当前的bean没有带 @Configuration 则属性添加为 lite
			//checkConfigurationClassCandidate()判断是否是加了注解的类
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				//存储在configCandidates集合中
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// Return immediately if no @Configuration classes were found
		if (configCandidates.isEmpty()) {
			return;
		}

		// Sort by previously determined @Order value, if applicable
		//如果有bean加了@Order注解的,进行排序,没有的默认排序,不是重点
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return Integer.compare(i1, i2);
		});
		//不是重点
		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();
		}

		//实例化ConfigurationClassParser,为了解析各个配置类
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

         //有创建两个集合,去掉重复的配置类
		//因为有可能有重复的配置类,Spring内部提供的话是不可能有重复的,但是你提供的话就有可能重复的,你可以一次性提供多个同样的配置类进入
		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		do {
			//扫描包,其实还有 其他功能的,这是Spring非常核心的功能
			//此时的candidates中其实就只有一个配置类  parse根据配置类开始扫描带有注解的类
            //点击这个方法
			parser.parse(candidates);
			parser.validate();
			//把读取出来的类实现了 ImportSelector 返回的类集合赋值给 configClasses集合
			//parser.getConfigurationClasses() 把我们解析器存储好的类拿出来了,准备把 实现了 ImportSelector接口返回的类注册到map中
			Set<ConfigurationClass> 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());
			}
			//在这里把@Import里面的返回的类,放到bean工厂的map集合中
			//configClasses集合添加到bean工厂的map集合中
			//@Import中填写的类有三种形式
			//1.ImportSelector 2.ImportBeanDefinitionRegistrar 3.普通类
			//通俗地来说如果每个类使用了 @Import导入某个类
			//1.实现了ImportSelector的类 ,把重写方法返回的全类名生成的beanDefinition存储在了configClasses集合中
			//2.实现了ImportBeanDefinitionRegistrar接口的类,里面的beanDefinition也被放到configClasses集合中
			//3.普通的类也是一样
			//其实configClasses存储所有的beanDefinition,在这个方法里面还会进行判断
			//看哪个beanDefinition是实现了mportSelector,哪个类里面是有@Bean的
			//哪个是 实现ImportBeanDefinitionRegistrar的
			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());

		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
		if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
			sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
		}

		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			// Clear cache in externally provided MetadataReaderFactory; this is a no-op
			// for a shared cache since it'll be cleared by the ApplicationContext.
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}

9.点击 `parser.parse(candidates);`

candidates为用户所有配置类的集合

public void parse(Set<BeanDefinitionHolder> configCandidates) {
		//遍历每个beanHolder,其实这个bean中都是被加了注解的
		//其实一般就是配置类configCandidates只有一个
		for (BeanDefinitionHolder holder : configCandidates) {
			//获取每个beanDefinition
			BeanDefinition bd = holder.getBeanDefinition();
			try {
				//判断当前的bean时候是被加注解的,其实是肯定被加了注解的,前面已经做过判断了
				if (bd instanceof AnnotatedBeanDefinition) {
					//解析 把配置类的元数据对象 和 beanName传过去
                    //点击这个方法
					parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
				}
				//不是被加注解的,Spring内部的类
				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);
			}
		}

		this.deferredImportSelectorHandler.process();
	}

10.点击`parse`方法

	protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
		//创建了ConfigurationClass对象,也可以理解为一个临时的容器方便传参数
		//ConfigurationClass作为一个数据结构,重新把元数据和beanName存储起来
		processConfigurationClass(new ConfigurationClass(metadata, beanName));
	}

11.点击processConfigurationClass

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
		//是否要跳过解析,不是重点
		//这里的configClass就是元数据对象和beanName的数据结构
		if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
			return;
		}

		//处理Imported情况
		//当前的类有没有被其他的类导入
		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.
		//把configClass获取SourceClass对象,有封装了一个对象
		SourceClass sourceClass = asSourceClass(configClass);
		do {
			//点击这个方法
			sourceClass = doProcessConfigurationClass(configClass, sourceClass);
		}
		while (sourceClass != null);

		//扫描出来的所有的beanDefinition
		//多个递归调用之后,这个集合会存储着 所有的配置类,所有被加了注解的类,以及实现了 ImportSelector 接口返回的类
		this.configurationClasses.put(configClass, configClass);
	}

11.点击 doProcessConfigurationClass

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

		//判断当前的类是否有@Component注解
		if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
			// Recursively process any member (nested) classes first
			processMemberClasses(configClass, sourceClass);
		}

		// Process any @PropertySource annotations
		//处理@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");
			}
		}

		// Process any @ComponentScan annotations
		//处理 @ComponentScan 注解
		//一个类可以写多个@ComponentScan 注解 ,所以获取当前这个类所有@ComponentScan 注解
		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) {

    //这个方法就是把componentScans下所有的包扫描了,并且把beanDefinition存储在beanFactory中了
   //返回的就是当前包下所有的beanDefinition
   //sourceClass.getMetadata().getClassName()  当前类的全类名
   //componentScan 当前类的注解对象
   //scannedBeanDefinitions 返回的集合存储了被扫描出来的beanDefinition
				Set<BeanDefinitionHolder> scannedBeanDefinitions =
                    //点击这个
						this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());

//scannedBeanDefinitions集合里面的所有bean已经被存储在beanFactory的map集合中了
//现在再次遍历所有的bean,查看这些beanDefinition中时候也存在 @ComponetScan @Import 等等注解
			//如果有的话,也会进行注册到map集合中,    好精妙 太厉害了,厉害
				for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
					BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
					if (bdCand == null) {
						bdCand = holder.getBeanDefinition();
					}
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
				//重新开始执行这个过程,查看被放进map的bean有没有@ComponetScan,@Import等注解
				//递归判断
						parse(bdCand.getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

		// Process any @Import annotations
		//到这一步时所有带@Component等注解的类都被加进Spring的BeanDefinitionMap集合中了

		//处理 @Import 注解  @Import其实可以写三种类型的在里面
		//1. ImportSelector这个类  2.ImportBeanDefinitionRegistrar 3,普通的类
		// getImports(sourceClass) 其实是直接判断当前类是否有@Import注解 ,有的话拿出里面的类
		processImports(configClass, sourceClass, getImports(sourceClass), true);
        
        //省略剩余代码.....
		
	}

12.点击 `this.componentScanParser.parse`

public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
				componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

		//主要用来生成beanName的beanName生成器
		Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
		boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
		scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
				BeanUtils.instantiateClass(generatorClass));

		//web当中在学
		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 filter : componentScan.getAnnotationArray("includeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter)) {
				scanner.addIncludeFilter(typeFilter);
			}
		}

		//排除某些特定的类
		for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter)) {
				scanner.addExcludeFilter(typeFilter);
			}
		}

		//当前这个配置类 是否需要懒加载,其他类还没有扫描出来
		boolean lazyInit = componentScan.getBoolean("lazyInit");
		if (lazyInit) {
			scanner.getBeanDefinitionDefaults().setLazyInit(true);
		}

		Set<String> basePackages = new LinkedHashSet<>();
		String[] basePackagesArray = componentScan.getStringArray("basePackages");
		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));
	}

13.点击 `scanner.doScan`

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) {
			//扫描basePackage包下的java文件并把文件转换为BeanDefinition
			//这里面使用呢的asm扫描 Class文件
            //点击这个方法
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

			for (BeanDefinition candidate : candidates) {
				//当前的BeanDefinition是单例的,还是多例的
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);

				if (candidate instanceof AbstractBeanDefinition) {
					//现在这里的bean被扫描出来了
					//如果这个类是AbstractBeanDefinition子类 进来
					//设置一些默认lazy init属性
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					//虽然上面由给了默认值,但是我们用户也是可以修改默认值的
					//这里就判断该bean是否添加了lazy,Primary,DependsOn Role等注解
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}

				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					//这个是重点,  在这里终于把 扫描beanDefinition添加进bean工厂中
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

14.点击 `findCandidateComponents`

public Set<BeanDefinition> findCandidateComponents(String basePackage) {
		if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
			return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
		}
		else {
			//这里扫描
			return scanCandidateComponents(basePackage);
		}
	}

15.点击 `scanCandidateComponents`

在这个方法中,Spring使用了 asm技术读取@ComponentScan包下所有的类,

判断该类有没有写 @Component

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		//加了注解资源被暂时存储在这里
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
			//使用的是asm读取class文件
			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) {
				if (traceEnabled) {
					logger.trace("Scanning " + resource);
				}
				if (resource.isReadable()) {
					try {
						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
					//判断当前的class文件是否加注解
						if (isCandidateComponent(metadataReader)) {
//sbd元数据对象 ScannedGenericBeanDefinition 继承 GenericBeanDefinition 继承 AbstractBeanDefinition
//给加了注解的类创建描述类                            
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setResource(resource);
							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 (Throwable ex) {
						throw new BeanDefinitionStoreException(
								"Failed to read candidate component class: " + resource, ex);
					}
				}
				else {
					if (traceEnabled) {
						logger.trace("Ignored because not readable: " + resource);
					}
				}
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
		}
    //返回集合
		return candidates;
	}

16.回到 `doScan`中

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) {
			//扫描basePackage包下的java文件并把文件转换为BeanDefinition
			//这里面使用呢的asm扫描 Class文件
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

			for (BeanDefinition candidate : candidates) {
				//当前的BeanDefinition是单例的,还是多例的
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);

				if (candidate instanceof AbstractBeanDefinition) {
					//现在这里的bean被扫描出来了
					//如果这个类是AbstractBeanDefinition子类 进来
					//设置一些默认lazy init属性
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					//虽然上面由给了默认值,但是我们用户也是可以修改默认值的
					//这里就判断该bean是否添加了lazy,Primary,DependsOn Role等注解
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}

				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					//这个是重点,  在这里终于把 扫描beanDefinition添加进bean工厂中
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

17.点击 `registerBeanDefinition`

	protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
	}

18.点击 `registerBeanDefinition`

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		//获取beanName的名称
		String beanName = definitionHolder.getBeanName();
		//现在把definitionHolder拆分了,又把 AnnotatedGenericBeanDefinition拿出来了
		//似乎definitionHolder就只是封装了一下,然后又给拆分, 可以理解为一个临时的容器
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		//这个不重要,spring当中处理别名的
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

19.Ctrl+Alt+B 点击 `registry.registerBeanDefinition`

@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}

		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					//这个地方把Spring扫描用户定义的bean存储到map集合中
					this.beanDefinitionMap.put(beanName, beanDefinition);
					//每添加一个对象进 map集合中 beanDefinitionNames 长度加1
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
				// Still in startup registration phase
				//在这个方法中就把 beanDefinition 存储在 DefaultListableBeanFactory的map集合中
				//顾名思义,beanDefinitionMap就是一个存储beanDefinition的map集合
				//在这个集合当中还有Spring当中本身已经初始好的对象
				this.beanDefinitionMap.put(beanName, beanDefinition);
				//把beanName存储在这个list集合中
				this.beanDefinitionNames.add(beanName);
				//这个是去重的,不是重点
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}

最后把扫描出来的组件封装成 BeanDefinition添加到map集合中

呀呀好复杂啊,你要是仔细看完了,你就是这条街最亮的仔

Spring5源码地址:

github.com/zouchangfu/… gitee.com/zouchangfu/…

Spring5源码都是已经构建好的了,无需再使用gradle进行构建了,直接打开就可以跑起来