在 spring 中,为简化 bean 的配置,在 spring-context 模块下提供了包的自动扫描功能,将配置的包及其子包下的所有符合条件的类都注册到 BeanFactory 中。下面来看下具体是怎么实现的。
配置
<context:component-scan base-package="com.icheetor.annotation.service"/>
配置很简单,但背后要实现的功能确比较复杂,先来看看 spring 对这段配置的解析。
解析
在 META-INF/spring.handlers 文件中,找到自定义标签 context 对应的 handler 为 ContextNamespaceHandler,查看 ContextNamespaceHandler#init 方法,name 为 component-scan 对应的解析器为 ComponentScanBeanDefinitionParser,进入 ComponentScanBeanDefinitionParser#parse 方法。
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);// 扫描 bean 定义,并注册它们// 1.配置扫描器ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);// 2.执行扫描,得到 BeanDefinition 并注册到 BeanFactorySet<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);// 3.注册注解相关后置处理器registerComponents(parserContext.getReaderContext(), beanDefinitions, element);return null;
}
先是对 basePackage 的解析,此处也支持 "${...}" 占位符,但这种一开始 xml 解析时,由 spring 中的属性解析器 PropertyResolver 可知,所支持的占位字符串很有限。basePackage 也支持多个包的配置,以 "," 或 ";" 分隔即可,将 basePackage 解析为名称为 basePackages 的 String 数组。
此处解析 basePackage 中占位符时采用的策略很宽松,resolvePlaceholders,没有默认值的无法解析占位符将被忽略,并原封不动地传递。
解析完 basePackage,接着进行扫描器的配置,有了路径,还需要工具来执行。
扫描器配置
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {boolean useDefaultFilters = true;// 使用默认过滤器,默认 trueif (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {useDefaultFilters = Boolean.parseBoolean(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));}// Delegate bean definition registration to scanner class.ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));}try {// 解析 name-generatorparseBeanNameGenerator(element, scanner);}catch (Exception ex) {parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());}try {parseScope(element, scanner);}catch (Exception ex) {parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());}// 解析子标签,是否存在 include-filter 或 exclude-filterparseTypeFilters(element, scanner, parserContext);return scanner;
}protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,readerContext.getEnvironment(), readerContext.getResourceLoader());
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment, @Nullable ResourceLoader resourceLoader) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");// registry 即 BeanFactorythis.registry = registry;if (useDefaultFilters) {registerDefaultFilters();}// 全局 Environment,创建 ApplicationContext 时创建setEnvironment(environment);// ApplicationContext 继承 ResourceLoader,当采用 ClassPathXmlApplicationContext,此处 resourceLoader 即 ClassPathXmlApplicationContextsetResourceLoader(resourceLoader);
}
// 注册默认过滤器
protected void registerDefaultFilters() {this.includeFilters.add(new AnnotationTypeFilter(Component.class));ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.}try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}
}
注册过滤器,默认只对 @Component 注解标识的类进行注册。
设置 ResourceLoader,用于对资源文件进行解析加载。
@Override
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);// 加载 META-INF/spring.components 下配置的候选的 Component,是一个扩展,默认 nullthis.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());
}
此处resourceLoader 若为 ApplicationContext 子类,则获取的 resourcePatternResolver 就是 resourceLoader。
public CachingMetadataReaderFactory(@Nullable ResourceLoader resourceLoader) {super(resourceLoader);if (resourceLoader instanceof DefaultResourceLoader) {this.metadataReaderCache =((DefaultResourceLoader) resourceLoader).getResourceCache(MetadataReader.class);}else {setCacheLimit(DEFAULT_CACHE_LIMIT);}
}
// CachingMetadataReaderFactory 父类
public SimpleMetadataReaderFactory(@Nullable ResourceLoader resourceLoader) {this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
}// DefaultResourceLoader
public <T> Map<Resource, T> getResourceCache(Class<T> valueType) {// resourceCaches 为一 ConcurrentHashMap,对 computeIfAbsent 进行了重写,此时返回值为计算出的值return (Map<Resource, T>) this.resourceCaches.computeIfAbsent(valueType, key -> new ConcurrentHashMap<>());
}
类的元数据读取,resourceLoader 若为 AbstractApplicationContext 子类,则就是 DefaultResourceLoader 子类。在 DefaultResourceLoader.resourceCaches 中放入 key 为 MetadataReader.class,value 为一个 ConcurrentHashMap 实例对象。
配置完成,将 ClassPathBeanDefinitionScanner 实例对象返回。
扫描
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();// 遍历 basePackagesfor (String basePackage : basePackages) {Set<BeanDefinition> candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {// 解析 @ScopeScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);// 设置 AbstractBeanDefinition 属性if (candidate instanceof AbstractBeanDefinition) {postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}// 设置其它注解属性,存在的话,@Lazy/@Primary/@DependsOn/@Role/@Descriptionif (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}// 校验 beanName 是否已经存在if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);// 加入结果集beanDefinitions.add(definitionHolder);// 注册 beanDefinitionregisterBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;
}
遍历 basePackages,获取 basePackage 下的候选的 BeanDefinition。
public Set<BeanDefinition> findCandidateComponents(String basePackage) {// 默认 nullif (this.componentsIndex != null && indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}else {return scanCandidateComponents(basePackage);}
}private Set<BeanDefinition> scanCandidateComponents(String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();try {// classpath*:com/icheetor/annotation/service/**/*.classString packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +resolveBasePackage(basePackage) + '/' + this.resourcePattern;Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);for (Resource resource : resources) {try {MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);if (isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);sbd.setSource(resource);if (isCandidateComponent(sbd)) {...candidates.add(sbd);}else {...}}else {...}}catch (FileNotFoundException ex) {...}catch (Throwable ex) {...}}}catch (IOException ex) {...}return candidates;
}protected String resolveBasePackage(String basePackage) {return ClassUtils.convertClassNameToResourcePath(getEnvironment().resolveRequiredPlaceholders(basePackage));
}
先将配置的 basePackage 包名解析为包搜索路径的指定模式,此处针对 "com.icheetor.annotation.service" 解析出的 packageSearchPath 为:
classpath*:com/icheetor/annotation/service/**/*.class
此时解析 basePackage 中的 "${...}" 采用严格的解析策略,因为后面要直接根据路径搜索,所以此处遇到无法解析的占位符直接抛出异常。
接着利用创建 ClassPathBeanDefinitionScanner 时调用 setResourceLoader 设置的 resourcePatternResolver 获取资源文件。从上面介绍可知,这就是 AbstractApplicationContext 子类。
// AbstractApplicationContext
@Override
public Resource[] getResources(String locationPattern) throws IOException {return this.resourcePatternResolver.getResources(locationPattern);
}
public AbstractApplicationContext() {this.resourcePatternResolver = getResourcePatternResolver();
}
protected ResourcePatternResolver getResourcePatternResolver() {return new PathMatchingResourcePatternResolver(this);
}
转化为利用创建 AbstractApplicationContext 时创建的 PathMatchingResourcePatternResolver 实例对象,获取资源文件,获取的详细过程参考 spring 中的资源文件加载。
此处根据匹配后缀 "**/*.class" 匹配到的都是 class 字节码文件,接着遍历返回的 resources,此处由于是 class 文件,将其封装为 FileSystemResource。
在前面的扫描器配置 setResourceLoader 中,创建了 CachingMetadataReaderFactory 实例对象,赋值给 metadataReaderFactory,所以此时调用 ClassPathScanningCandidateComponentProvider#getMetadataReaderFactory 时返回的就是前面创建的 CachingMetadataReaderFactory 实例对象。接着调用 CachingMetadataReaderFactory#getMetadataReader。
// CachingMetadataReaderFactory
@Override
public MetadataReader getMetadataReader(Resource resource) throws IOException {if (this.metadataReaderCache instanceof ConcurrentMap) {// 先从缓存获取MetadataReader metadataReader = this.metadataReaderCache.get(resource);if (metadataReader == null) {// 不存在,通过父类进行创建metadataReader = super.getMetadataReader(resource);this.metadataReaderCache.put(resource, metadataReader);}return metadataReader;}else if (this.metadataReaderCache != null) {synchronized (this.metadataReaderCache) {MetadataReader metadataReader = this.metadataReaderCache.get(resource);if (metadataReader == null) {metadataReader = super.getMetadataReader(resource);this.metadataReaderCache.put(resource, metadataReader);}return metadataReader;}}else {return super.getMetadataReader(resource);}
}
// SimpleMetadataReaderFactory
@Override
public MetadataReader getMetadataReader(Resource resource) throws IOException {return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());
}
CachingMetadataReaderFactory 是 SimpleMetadataReaderFactory 子类,相对于父类扩展了缓存 MetadataReader 的功能。
SimpleMetadataReader 的创建可参考 spring 中的字节码文件访问 -- classreading 包。
获取到 metadataReader 实例对象后,调用 ClassPathScanningCandidateComponentProvider#isCandidateComponent,判断是否是合格的候选者。
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {for (TypeFilter tf : this.excludeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return false;}}for (TypeFilter tf : this.includeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return isConditionMatch(metadataReader);}}return false;
}
通过配置的 excludeFilters 和 includeFilters 对 metadataReader 进行匹配。匹配代码比较长,核心逻辑就是,利用 SimpleMetadataReader 中的 annotations,即 MergedAnnotationsCollection,遍历其中的 AnnotationTypeMappings 数组,接着遍历 AnnotationTypeMappings 中的 AnnotationTypeMapping 集合,获取其中的 annotationType 与指定注解类型进行匹配。
// MergedAnnotationsCollection
private <A extends Annotation> MergedAnnotation<A> find(Object requiredType,@Nullable Predicate<? super MergedAnnotation<A>> predicate,@Nullable MergedAnnotationSelector<A> selector) {if (selector == null) {// 默认选择器selector = MergedAnnotationSelectors.nearest();}MergedAnnotation<A> result = null;for (int i = 0; i < this.annotations.length; i++) {MergedAnnotation<?> root = this.annotations[i];AnnotationTypeMappings mappings = this.mappings[i];// 遍历 AnnotationTypeMappings 中的 mappingsfor (int mappingIndex = 0; mappingIndex < mappings.size(); mappingIndex++) {AnnotationTypeMapping mapping = mappings.get(mappingIndex);if (!isMappingForType(mapping, requiredType)) {continue;}// 匹配到了MergedAnnotation<A> candidate = (mappingIndex == 0 ? (MergedAnnotation<A>) root :TypeMappedAnnotation.createIfPossible(mapping, root, IntrospectionFailureLogger.INFO));if (candidate != null && (predicate == null || predicate.test(candidate))) {// 判断 distance == 0if (selector.isBestCandidate(candidate)) {return candidate;}// result 赋值result = (result != null ? selector.select(result, candidate) : candidate);}}}return result;
}
private static boolean isMappingForType(AnnotationTypeMapping mapping, @Nullable Object requiredType) {if (requiredType == null) {return true;}Class<? extends Annotation> actualType = mapping.getAnnotationType();return (actualType == requiredType || actualType.getName().equals(requiredType));
}
注解类型符合过滤条件,创建 BeanDefinition。
public ScannedGenericBeanDefinition(MetadataReader metadataReader) {Assert.notNull(metadataReader, "MetadataReader must not be null");this.metadata = metadataReader.getAnnotationMetadata();setBeanClassName(this.metadata.getClassName());setResource(metadataReader.getResource());
}
之后将 ScannedGenericBeanDefinition 实例对象加入 candidates 返回。
接着遍历 candidates。执行 this.scopeMetadataResolver.resolveScopeMetadata(candidate),其目的是查看类上面是否有 @Scope 注解,存在,解析其上的 value 和 proxyMode 属性,之后将封装的 ScopeMetadata 实例对象返回。
ScopeMetadata 中默认 scopeName 为 "singleton"。
接着采用 AnnotationBeanNameGenerator 来生成 beanName。
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {if (definition instanceof AnnotatedBeanDefinition) {// 解析注解 value 属性获取 beanNameString beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);if (StringUtils.hasText(beanName)) {// Explicit bean name found.return beanName;}}// 注解未配置 beanName,创建默认 beanName,类名首字母小写return buildDefaultBeanName(definition, registry);
}
@Nullable
protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {AnnotationMetadata amd = annotatedDef.getMetadata();// 获取注解类型Set<String> types = amd.getAnnotationTypes();String beanName = null;for (String type : types) {// 解析 type 上属性,得到 AnnotationAttributesAnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);if (attributes != null) {// 解析 type 上 meta-type // 举例: @Service meta-type @Component @Component 上 meta-type @Indexed,所以返回的 metaTypes 会包含 @Component 和 @IndexedSet<String> metaTypes = this.metaAnnotationTypesCache.computeIfAbsent(type, key -> {Set<String> result = amd.getMetaAnnotationTypes(key);return (result.isEmpty() ? Collections.emptySet() : result);});// metaTypes 是否含有 @Component,attributes 是否含有 value 属性if (isStereotypeWithNameValue(type, metaTypes, attributes)) {Object value = attributes.get("value");if (value instanceof String) {String strVal = (String) value;if (StringUtils.hasLength(strVal)) {if (beanName != null && !strVal.equals(beanName)) {throw ...}beanName = strVal;}}}}}return beanName;
}
注解上存在 value 属性,解析后将其作为 beanName,不存在创建一个默认 beanName,即类名首字母小写。
接着为 beanDefinition 设置相关属性,分别调用 ClassPathBeanDefinitionScanner#postProcessBeanDefinition 和 AnnotationConfigUtils#processCommonDefinitionAnnotations 两个方法。
最后,完成 beanDefintion 注册。也就是说,在扫描的这一步就已经完成了 BeanDefinition 的注册。
注册后置处理器
接着,在 BeanFactory 中注册所有注解相关的后置处理器。
// ComponentScanBeanDefinitionParser
protected void registerComponents(XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {Object source = readerContext.extractSource(element); // nullCompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));}// Register annotation config processors, if necessary.boolean annotationConfig = true;if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {annotationConfig = Boolean.parseBoolean(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));}if (annotationConfig) {Set<BeanDefinitionHolder> processorDefinitions =AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);for (BeanDefinitionHolder processorDefinition : processorDefinitions) {compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));}}readerContext.fireComponentRegistered(compositeDef);
}// AnnotationConfigUtils
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {// beanFactory 设置 dependencyComparatorbeanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {// beanFactory 设置 autowireCandidateResolverbeanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);// BeanDefinitionRegistryPostProcessor 实现类// org.springframework.context.annotation.internalConfigurationAnnotationProcessorif (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}// BeanPostProcessor 实现类,实例化时使用// org.springframework.context.annotation.internalAutowiredAnnotationProcessorif (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));}catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);}def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}// BeanFactoryPostProcessor 实现类// org.springframework.context.event.internalEventListenerProcessorif (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}// EventListenerFactory 接口// org.springframework.context.event.internalEventListenerFactoryif (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;
}// 注册内部后置处理器对应的 BeanDefinition
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);registry.registerBeanDefinition(beanName, definition);return new BeanDefinitionHolder(definition, beanName);
}
只有 beanFactory 中的 dependencyComparator 和 autowireCandidateResolver 属性直接设置的是实例对象,其它内部的后置处理器都是作为 BeanDefinition 先注册在 BeanFactory 中,待 AbstractApplicationContext#refresh 中执行 invokeBeanFactoryPostProcessors 和 registerBeanPostProcessors 时通过 beanFactory.getBean 创建实例对象,完成后置处理器的注册。
此处还有一点要注意,就是 autowireCandidateResolver,看似只创建了 ContextAnnotationAutowireCandidateResolver 一个实例对象,但由于继承关系,实际上也获得了处理处理其它注解的能力。其类结构如下:
这样,就完成了基于注解的包扫描模式下的 BeanDefinition 的注册,也完成了对 context 标签下 component-scan 的解析。