Spring IOC系列学习笔记五:context:component-scan 节点解析

原文地址程序员囧辉大佬

相关文章

Spring IOC系列学习笔记一:前置刷新
Spring IOC系列学习笔记二:obtainFreshBeanFactory方法
Spring IOC系列学习笔记三:parseDefaultElement详解
Spring IOC系列学习笔记四:parseCustomElement解析
Spring IOC系列学习笔记五:context:component-scan 节点解析
Spring IOC系列学习笔记六:invokeBeanFactoryPostProcessors解析
Spring IOC系列学习笔记七:registerBeanPostProcessors
Spring IOC系列学习笔记八:finishBeanFactoryInitialization
Spring IOC系列学习笔记九:getBean方法
Spring IOC系列学习笔记十:createBean方法(上)
Spring IOC系列学习笔记十一:createBean方法(下)
Spring IOC系列学习笔记十二:@Autowire注解


前言

前面我们已经介绍了自定义节点的解析。我们以context:component-scan 节点为例子进行讲解。在findParserForElement方法后返回的是ComponentScanBeanDefinitionParser类,在该类中进行解析。

代码块一:parse

	@Override
	@Nullable
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		1、获取base-package标签地址
		String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
		1.1、解决占位符
		basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
		1.3、分割,号成数组
		String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
				ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

		// Actually scan for bean definitions and register them.
		2、把节点封装成ClassPathBeanDefinitionScanner供以后解析
		ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
		3、扫描配置的包下面的地址,返回已经解析的bean
		Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
		4、注册组件(包括注册一些内部的注解后置处理器、触发注册事件)
		registerComponents(parserContext.getReaderContext(), beanDefinitions, element);

		return null;
	}

2、把节点封装成ClassPathBeanDefinitionScanner供以后解析代码块二
3、扫描配置的包下面的地址,返回已经解析的bean见代码块六
4、注册组件(包括注册一些内部的注解后置处理器、触发注册事件)见代码块十五

代码块二:configureScanner

protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
		1、使用默认的过滤器,也可以自己配置
		boolean useDefaultFilters = true;
		if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
			useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
		}

		// Delegate bean definition registration to scanner class.
		2、将bean定义委托给ClassPathBeanDefinitionScanner
		ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
		scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
		scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
		3、解析resource-pattern
		if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
			scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
		}

		try {
		4、解析 name-generator
			parseBeanNameGenerator(element, scanner);
		}
		catch (Exception ex) {
			parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
		}

		try {
			5、解析Scope
			parseScope(element, scanner);
		}
		catch (Exception ex) {
			parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
		}
		6、解析类型过滤器属性
		parseTypeFilters(element, scanner, parserContext);

		return scanner;
	}

2、将bean定义委托给ClassPathBeanDefinitionScanner见代码块三
6、解析类型过滤器属性代码块五
其他方法不做解析,都大同小异,就是解析配置的各个属性

代码块三:createScanner

	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");
		this.registry = registry;

		if (useDefaultFilters) {
			1、注册默认的过滤器
			registerDefaultFilters();
		}
		setEnvironment(environment);
		setResourceLoader(resourceLoader);
	}

1、注册默认的过滤器见代码块四

代码块四:registerDefaultFilters

		protected void registerDefaultFilters() {
			1@Component放入缓存
		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
		try {
			2@ManagedBean放入缓存
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
			logger.debug("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 {
			3@Named放入缓存
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
			logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

该方法执行完之后,includeFilters缓存中只会有@Component这一个注解,因为另外两个new AnnotationTypeFilter()会抛出异常,而没有加入到缓存当中。

代码块五:parseTypeFilters

	protected void parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext) {
		// Parse exclude and include filter elements.
		ClassLoader classLoader = scanner.getResourceLoader().getClassLoader();
		1、获得所有的子节点 例如: <context:exclude-filter type="regex" expression="aaa"/>
		NodeList nodeList = element.getChildNodes();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				2、拿到节点的name
				例如节点:<context:exclude-filter type="" expression=""/>,localName为:exclude-filter
				String localName = parserContext.getDelegate().getLocalName(node);
				try {
					if (INCLUDE_FILTER_ELEMENT.equals(localName)) {
						3.1、创建TypeFilter
						TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
						3.2、添加到scanner中
						scanner.addIncludeFilter(typeFilter);
					}
					else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) {
						4.1、创建TypeFilter
						TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
						4.2、添加到scanner中
						scanner.addExcludeFilter(typeFilter);
					}
				}
				catch (Exception ex) {
					parserContext.getReaderContext().error(
							ex.getMessage(), parserContext.extractSource(element), ex.getCause());
				}
			}
		}
	}


		protected TypeFilter createTypeFilter(
			Element element, @Nullable ClassLoader classLoader, ParserContext parserContext) {
		5、获取type的值
		String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE);
		6、获取expression的值
		String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE);
		expression = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(expression);
		try {
			5.1、根据不同的filterType返回不同的实例,比如annotation返回AnnotationTypeFilter
			if ("annotation".equals(filterType)) {
				return new AnnotationTypeFilter((Class<Annotation>) ClassUtils.forName(expression, classLoader));
			}
			5.2、指定过滤的类或接口, 包括子类和子接口, expression为类全名称
			else if ("assignable".equals(filterType)) {
				return new AssignableTypeFilter(ClassUtils.forName(expression, classLoader));
			}
			5.3、 指定aspectj表达式来过滤类, expression为aspectj表达式字符串
			else if ("aspectj".equals(filterType)) {
				return new AspectJTypeFilter(expression, classLoader);
			}
			5.4、正则表达式 expression为表达式
			else if ("regex".equals(filterType)) {
				return new RegexPatternTypeFilter(Pattern.compile(expression));
			}
			5.5、用户自定义过滤器类型, expression为自定义过滤器的类全名称
			else if ("custom".equals(filterType)) {
				Class<?> filterClass = ClassUtils.forName(expression, classLoader);
				if (!TypeFilter.class.isAssignableFrom(filterClass)) {
					throw new IllegalArgumentException(
							"Class is not assignable to [" + TypeFilter.class.getName() + "]: " + expression);
				}
				return (TypeFilter) BeanUtils.instantiateClass(filterClass);
			}
			else {
				throw new IllegalArgumentException("Unsupported filter type: " + filterType);
			}
		}
		catch (ClassNotFoundException ex) {
			throw new FatalBeanException("Type filter class not found: " + expression, ex);
		}
	}

configureScanner方法解析完毕,下面回到代码块一:3开始进入扫描doScan方法。

代码块六: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) {
			1、扫描basePackage,将符合要求的bean定义全部找出来
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			for (BeanDefinition candidate : candidates) {
				2、解析@Scope属性
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				3、根据beanName生成beanName
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					4、进一步解析bean
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					5、处理定义在目标类上的通用注解,包括@Lazy, @Primary, @DependsOn, @Role, @Description
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				6、检查bean是否注册过,检查是否兼容
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
					7、根据proxyMode的值(步骤4中解析), 选择是否创建作用域代理
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					8、注册bean到缓存中(注册到beanDefinitionMap、beanDefinitionNames、aliasMap缓存)前面已经解析过
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

1、扫描basePackage见代码块七
2、解析Scope属性见代码块九
4、进一步解析bean见代码块十
5、处理定义在目标类上的通用注解见代码块十一
6、检查bean是否注册过,检查是否兼容见代码块十二
7、根据proxyMode的值见代码块十三
8、注册bean到缓存中已经解析过见Spring系列学习笔记三:代码块十四

代码块七:findCandidateComponents

		public Set<BeanDefinition> findCandidateComponents(String basePackage) {
		1、从索引中获取候选的bean 例:@Indexed  这是spring5推出的新的注解 目前没用过不熟悉
		if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
			return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
		}
		else {
			2、扫描候选组件
			return scanCandidateComponents(basePackage);
		}
	}

2、扫描候选组件见代码块八

代码块八:scanCandidateComponents

	private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
			1、要扫描的路径:例:classpath*:com/zgf/**/*.class
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			2、扫描出该路径下所有的资源
			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 {
						3、用MetadataReader访问该元数据
						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
						4、判断是否是候选bean,就是用includeFilters和excludeFilters进行判断一下。
						if (isCandidateComponent(metadataReader)) {
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setResource(resource);
							sbd.setSource(resource);
							5、二次判断判断是否是候选类
							if (isCandidateComponent(sbd)) {
								if (debugEnabled) {
									logger.debug("Identified candidate component class: " + resource);
								}
								6、确定是候选类,则添加到candidates
								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;
	}

	4、判断是否是候选bean
	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;
	}

		5、二次判断判断是否是候选类
		protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
		AnnotationMetadata metadata = beanDefinition.getMetadata();
		(是否独立&&(具体的实现||(抽象&&@Lookup注解)))
		return (metadata.isIndependent() && (metadata.isConcrete() ||
				(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
	}

findCandidateComponents方法结束 回到代码块六,开始解析Scop属性见代码块九

代码块九:resolveScopeMetadata

@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
    ScopeMetadata metadata = new ScopeMetadata();
    if (definition instanceof AnnotatedBeanDefinition) {
        AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
        AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
                annDef.getMetadata(), this.scopeAnnotationType);
        // 如果使用了@Scope注解
        if (attributes != null) {
            // 解析scopeName属性
            metadata.setScopeName(attributes.getString("value"));
            // 解析proxyMode属性
            ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
            if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) {
                proxyMode = this.defaultProxyMode;
            }
            metadata.setScopedProxyMode(proxyMode);
        }
    }
    return metadata;
}

如果使用了@Scope注解,则解析注解的属性。这边的 defaultProxyMode 取决于代码块1中步骤5的 scope-resolver、scoped-proxy 属性,默认为 ScopedProxyMode.NO。可以通过 scoped-proxy 来设置,例如下面配置 defaultProxyMode 的值就为 ScopedProxyMode.TARGET_CLASS。回到代码块六,进入postProcessBeanDefinition方法

    <context:component-scan  scoped-proxy="targetClass"  base-package="com.zgf">  
    </context:component-scan>

代码块十:postProcessBeanDefinition

protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
    // 给beanDefinition设置默认值
    beanDefinition.applyDefaults(this.beanDefinitionDefaults);
    if (this.autowireCandidatePatterns != null) {
        // 设置此bean是否可以自动装配到其他bean中, 默认为true
        beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
    }
}

代码块十一:processCommonDefinitionAnnotations

public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
		processCommonDefinitionAnnotations(abd, abd.getMetadata());
	}

	static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
		1@Lazy设置是否开启懒加载模式
		AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
		if (lazy != null) {
			abd.setLazyInit(lazy.getBoolean("value"));
		}
		else if (abd.getMetadata() != metadata) {
			lazy = attributesFor(abd.getMetadata(), Lazy.class);
			if (lazy != null) {
				abd.setLazyInit(lazy.getBoolean("value"));
			}
		}
		2@Primary当有多个bean匹配时候,用@Primary来区分同@Autowired@Quealifier组合
		if (metadata.isAnnotated(Primary.class.getName())) {
			abd.setPrimary(true);
		}
		3@DependsOn注解
		AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
		if (dependsOn != null) {
			abd.setDependsOn(dependsOn.getStringArray("value"));
		}
		
		if (abd instanceof AbstractBeanDefinition) {
			AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
			4@Role注解
			AnnotationAttributes role = attributesFor(metadata, Role.class);
			if (role != null) {
				absBd.setRole(role.getNumber("value").intValue());
			}
			5@Description注解
			AnnotationAttributes description = attributesFor(metadata, Description.class);
			if (description != null) {
				absBd.setDescription(description.getString("value"));
			}
		}
	}

回到代码块六继续解析。

代码块十二:checkCandidate

	protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
		1、判断是否已经注册过,如果没注册则返回true,开始注册
		if (!this.registry.containsBeanDefinition(beanName)) {
			return true;
		}
		2、获取注册的bean实例
		BeanDefinition existingDef = this.registry.getBeanDefinition(beanName);
		BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition();
		if (originatingDef != null) {
			3、将新的实例替换为原来注册的实例
			existingDef = originatingDef;
		}
		4、判断新的是否与旧的兼容,如果不兼容抛出异常,兼容返回false跳过注册
		if (isCompatible(beanDefinition, existingDef)) {
			return false;
		}
		throw new ConflictingBeanDefinitionException("Annotation-specified bean name '" + beanName +
				"' for bean class [" + beanDefinition.getBeanClassName() + "] conflicts with existing, " +
				"non-compatible bean definition of same name and class [" + existingDef.getBeanClassName() + "]");
	}

代码块十三:applyScopedProxyMode

static BeanDefinitionHolder applyScopedProxyMode(
        ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
 
    ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
    // 1.如果不需要创建代理,则直接返回bean定义
    if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
        return definition;
    }
    // 2.判断是使用基于类的代理还是基于接口的代码, 基于类: 使用CGLIB代理, 基于接口: 使用JDK动态代理
    boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
    // 3.使用相应的代理模式, 创建一个scope代理
    return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}

3.使用相应的代理模式, 创建一个scope代理见代码块十四

代码块十四:createScopedProxy

	public static BeanDefinitionHolder createScopedProxy(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) {

		return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass);
	}

	public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
			BeanDefinitionRegistry registry, boolean proxyTargetClass) {
		1、获取原始的beanName
		String originalBeanName = definition.getBeanName();
		2、原始的bean定义
		BeanDefinition targetDefinition = definition.getBeanDefinition();
		3、生成一个代理的bean名字
		String targetBeanName = getTargetBeanName(originalBeanName);

		// Create a scoped proxy definition for the original bean name,
		// "hiding" the target bean in an internal target definition.
		RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
		proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
		4、设置代理bean的原始属性值
		proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
		proxyDefinition.setSource(definition.getSource());
		proxyDefinition.setRole(targetDefinition.getRole());

		proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
		if (proxyTargetClass) {
			5、根据类做代理
			targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
			// ScopedProxyFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here.
		}
		else {
			6、根据接口做代理
			proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
		}

		// Copy autowire settings from original bean definition.
		7、从原始bean定义复制autowire设置
		proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
		proxyDefinition.setPrimary(targetDefinition.isPrimary());
		if (targetDefinition instanceof AbstractBeanDefinition) {
			proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
		}

		// The target bean should be ignored in favor of the scoped proxy.
		targetDefinition.setAutowireCandidate(false);
		targetDefinition.setPrimary(false);
		8、注册原始bean
		// Register the target bean as separate bean in the factory.
		registry.registerBeanDefinition(targetBeanName, targetDefinition);
		9、将代理bean封装成BeanDefinitionHolder对象并返回
		// Return the scoped proxy definition as primary bean definition
		// (potentially an inner bean).
		return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
	}

回到代码块六开始注册bean。

代码块十五:registerComponents

protected void registerComponents(
        XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
 
    Object source = readerContext.extractSource(element);
    // 1.使用注解的tagName(例如: context:component-scan)和source 构建CompositeComponentDefinition
    CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
 
    // 2.将扫描到的所有BeanDefinition添加到compositeDef的nestedComponents属性中
    for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
        compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
    }
 
    // Register annotation config processors, if necessary.
    boolean annotationConfig = true;
    if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
        // 3.获取component-scan标签的annotation-config属性值(默认为true)
        annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
    }
    if (annotationConfig) {
        // 4.如果annotation-config属性值为true,在给定的注册表中注册所有用于注解的Bean后置处理器
        Set<BeanDefinitionHolder> processorDefinitions =
                AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
        for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
            // 5.将注册的注解后置处理器的BeanDefinition添加到compositeDef的nestedComponents属性中
            compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
        }
    }
 
    // 6.触发组件注册事件,默认实现为EmptyReaderEventListener(空实现,没有具体操作)
    readerContext.fireComponentRegistered(compositeDef);
}

4.在给定的注册表中注册所有用于注解的 bean 后置处理器,见代码块十六详解。

代码块十六:registerAnnotationConfigProcessors

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
        BeanDefinitionRegistry registry, Object source) {
 
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            // 1.设置dependencyComparator属性
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            // 2.设置autowireCandidateResolver属性(设置自动注入候选对象的解析器,用于判断BeanDefinition是否为候选对象)
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }
 
    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
 
    // 3.注册内部管理的用于处理@Configuration注解的后置处理器的bean
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        // 3.1 registerPostProcessor: 注册BeanDefinition到注册表中
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
 
    // 4.注册内部管理的用于处理@Autowired、@Value、@Inject以及@Lookup注解的后置处理器的bean
    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));
    }
 
    // 5.注册内部管理的用于处理@Required注解的后置处理器的bean
    if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
 
    // 6.注册内部管理的用于处理JSR-250注解(例如@Resource, @PostConstruct, @PreDestroy)的后置处理器的bean
    // 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));
    }
 
    // 7.注册内部管理的用于处理JPA注解的后置处理器的bean
    // 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));
    }
 
    // 8.注册内部管理的用于处理@EventListener注解的后置处理器的bean
    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));
    }
    // 9.注册内部管理用于生产ApplicationListener对象的EventListenerFactory对象
    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;
}

3.1 注册后置处理器的 BeanDefinition 到注册表中见代码块十七

代码块十七:registerPostProcessor

private static BeanDefinitionHolder registerPostProcessor(
        BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
 
    // 1.设置role
    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    // 2.注册BeanDefinition
    registry.registerBeanDefinition(beanName, definition);
    // 3.封装成BeanDefinitionHolder并返回
    return new BeanDefinitionHolder(definition, beanName);
}

至此,context:component-scan 节点解析已经完成,主要做的事情有:

  • 扫描 base-package 目录,将使用了 @Component、@Controller、@Repository、@Service
    注解的 bean
    注册到注册表中(其实就是beanDefinitionMap、beanDefinitionNames、aliasMap缓存中),跟之前解析默认命名空间一样,也是在后续创建
    bean 时需要使用这些缓存。
  • 添加了几个内部的注解相关的后置处理器:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor
    等。

总结

同时,本文的结束,也标志着 obtainFreshBeanFactory 方法的详解正式结束。

简单来说,有以下几个主要操作:

  • 根据 web.xml 中 contextConfigLocation 配置的路径,读取 Spring 配置文件,并封装成
    Resource。

  • 根据 Resource 加载 XML 配置文件,并解析成 Document 对象 。

  • 拿到 Document 中的根节点,遍历根节点和所有子节点。

  • 根据命名空间,进行不同的解析,将 bean 节点内容解析成 BeanDefinition。

  • 将 BeanDefinition 注册到注册表中(也就是beanDefinitionMap、beanDefinitionNames、aliasMap缓存)。

执行完 obtainFreshBeanFactory 方法,我们得到了三个重要的对象:

  • 新的 BeanFactory。
  • beanDefinitionNames 缓存。
  • beanDefinitionMap 缓存。
    这三个对象在之后的 IoC 构建过程中会发挥重要的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值
>