spring 中包自动扫描之 component-scan 解析

在 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 的解析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潭影空人心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值