在 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 并注册到 BeanFactory
Set<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;
// 使用默认过滤器,默认 true
if (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-generator
parseBeanNameGenerator(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-filter
parseTypeFilters(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 即 BeanFactory
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();
}
// 全局 Environment,创建 ApplicationContext 时创建
setEnvironment(environment);
// ApplicationContext 继承 ResourceLoader,当采用 ClassPathXmlApplicationContext,此处 resourceLoader 即 ClassPathXmlApplicationContext
setResourceLoader(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,是一个扩展,默认 null
this.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<>();
// 遍历 basePackages
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 解析 @Scope
ScopeMetadata 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/@Description
if (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);
// 注册 beanDefinition
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
遍历 basePackages,获取 basePackage 下的候选的 BeanDefinition。
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
// 默认 null
if (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/**/*.class
String 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 中的 mappings
for (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 == 0
if (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 属性获取 beanName
String 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 上属性,得到 AnnotationAttributes
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
if (attributes != null) {
// 解析 type 上 meta-type
// 举例: @Service meta-type @Component @Component 上 meta-type @Indexed,所以返回的 metaTypes 会包含 @Component 和 @Indexed
Set<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); // null
CompositeComponentDefinition 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 设置 dependencyComparator
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
// beanFactory 设置 autowireCandidateResolver
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// BeanDefinitionRegistryPostProcessor 实现类
// org.springframework.context.annotation.internalConfigurationAnnotationProcessor
if (!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.internalAutowiredAnnotationProcessor
if (!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.internalEventListenerProcessor
if (!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.internalEventListenerFactory
if (!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 的解析。