1. 程式人生 > >Spring ioc容器啟動流程—obtainFreshBeanFactory

Spring ioc容器啟動流程—obtainFreshBeanFactory

        本文以XmlWebApplicationContext啟動為例說明spring ioc容器啟動流程。

        obtainFreshBeanFactory的主要工作是建立DefaultListableBeanFactory例項,解析xml配置檔案,註冊bean。

工作流程概覽


         obtainFreshBeanFactory的主要工作在AbstractRefreshableApplicationContext類中refreshBeanFactory方法中完成,這裡完成DefaultListableBeanFactory的建立及初始化,之後在XmlWebApplicationContext類中的loadBeanDefinitions(DefaultListableBeanFactory beanFactory)方法中將bean的load工作轉交給XmlBeanDefinitionReader。

核心工作流程

建立DefaultListableBeanFactory

AbstractRefreshableApplicationContext.java

protected DefaultListableBeanFactory createBeanFactory() {
	return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

解析xml配置檔案,即loadBeanDefinitions

資源形式的轉化過程


        xml配置檔案中的<bean>元素最終會解析例項化為BeanDefinition,註冊到DefaultListableBeanFactory。

configLocation到Resource

       利用resourceLoader屬性讀取相應的locationPattern為Resource:


InputSource到Document

        先對Resource的資源模式進行校驗,是.xsd還是.dtd方式解析等,XmlBeanDefinitionReader的屬性documentLoader(其為DefaultDocumentLoader型別)載入InputSource為Document,這裡關鍵步驟是用ResourceEntityResolver定位到xsd資源來幫助解析xml檔案:


Document到Element

       XmlBeanDefinitionReader建立DefaultBeanDefinitionDocumentReader例項,將解析工作交給它,DefaultBeanDefinitionDocumentReader初步解析Document,獲取根Element,建立BeanDefinitionParserDelegate例項,將解析Element分為兩大類:DefaultElement、CustomElement,其中DefaultElement包括<import>、<alias>、<bean>、巢狀的<beans>,其餘的都為CustomElement:


        DefaultBeanDefinitionDocumentReader解析Element過程中,利用代理模式,將解析工作委託給BeanDefinitionParserDelegate進行:

DefaultBeanDefinitionDocumentReader.java

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {  
	if (delegate.isDefaultNamespace(root)) { // Element的namespaceURI為空或為"http://www.springframework.org/schema/beans"  
		NodeList nl = root.getChildNodes();  
		for (int i = 0; i < nl.getLength(); i++) { // 迴圈遍歷所有Element元素的下一級  
			Node node = nl.item(i);  
			if (node instanceof Element) {  
				Element ele = (Element) node;  
				if (delegate.isDefaultNamespace(ele)) { // 是否為預設的namespaceUri  
					parseDefaultElement(ele, delegate); // 處理預設的namespaceUri Element  
				}  
				else {  
					delegate.parseCustomElement(ele); // 處理Custom Element  
				}  
			}  
		}  
	}  
	else {  
		delegate.parseCustomElement(root);  
	}  
}
解析預設的Element
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
	if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { // 解析import Element
		importBeanDefinitionResource(ele);
	}
	else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { // 解析alias Element
		processAliasRegistration(ele);
	}
	else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { // 解析bean Element
		processBeanDefinition(ele, delegate);
	}
	else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // 解析內嵌beans Element
		// recurse
		doRegisterBeanDefinitions(ele);
	}
}

解析<import>:

	protected void importBeanDefinitionResource(Element ele) {
		String location = ele.getAttribute(RESOURCE_ATTRIBUTE); // 獲取import element的resource屬性
		if (!StringUtils.hasText(location)) {
			getReaderContext().error("Resource location must not be empty", ele);
			return;
		}

		// Resolve system properties: e.g. "${user.dir}"
		location = environment.resolveRequiredPlaceholders(location);

		Set<Resource> actualResources = new LinkedHashSet<Resource>(4);

		// Discover whether the location is an absolute or relative URI
		boolean absoluteLocation = false;
		try {
			absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
		}
		catch (URISyntaxException ex) {
			// cannot convert to an URI, considering the location relative
			// unless it is the well-known Spring prefix "classpath*:"
		}

		// Absolute or relative?
		if (absoluteLocation) { // location是否為絕對路徑
			try {
				int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
				if (logger.isDebugEnabled()) {
					logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
				}
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error(
						"Failed to import bean definitions from URL location [" + location + "]", ele, ex);
			}
		}
		else {
			// No URL -> considering resource location as relative to the current file.
			try {
				int importCount;
				Resource relativeResource = getReaderContext().getResource().createRelative(location);
				if (relativeResource.exists()) {
					importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);   // 載入import指定的xml配置檔案
					actualResources.add(relativeResource);
				}
				else {
					String baseLocation = getReaderContext().getResource().getURL().toString();
					importCount = getReaderContext().getReader().loadBeanDefinitions(
							StringUtils.applyRelativePath(baseLocation, location), actualResources);
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
				}
			}
			catch (IOException ex) {
				getReaderContext().error("Failed to resolve current resource location", ele, ex);
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]",
						ele, ex);
			}
		}
		Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
		getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
	}

解析<bean>:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); // 解析Element為BeanDefinition
	if (bdHolder != null) {
		bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
		try {
			// 將BeanDefinition註冊到DefaultListableBeanFactory的beanDefinitionMap中
			BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
		}
		catch (BeanDefinitionStoreException ex) {
			getReaderContext().error("Failed to register bean definition with name '" +
					bdHolder.getBeanName() + "'", ele, ex);
		}
		// 傳送Component註冊的訊息
		getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
	}
}

BeanDefinitionParserDelegate.java

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
	return parseBeanDefinitionElement(ele, null);
}

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
	String id = ele.getAttribute(ID_ATTRIBUTE); // 獲取bean的id屬性
	String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);// 獲取bean的name屬性

	List<String> aliases = new ArrayList<String>();
	if (StringUtils.hasLength(nameAttr)) {
		String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
		aliases.addAll(Arrays.asList(nameArr));
	}

	String beanName = id;
	if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
		beanName = aliases.remove(0);
		if (logger.isDebugEnabled()) {
			logger.debug("No XML 'id' specified - using '" + beanName +
					"' as bean name and " + aliases + " as aliases");
		}
	}

	if (containingBean == null) {
		checkNameUniqueness(beanName, aliases, ele);
	}

	// 這裡解析Element為GenericBeanDefinition
	AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
	if (beanDefinition != null) {
		if (!StringUtils.hasText(beanName)) {
			try {
				if (containingBean != null) {
					beanName = BeanDefinitionReaderUtils.generateBeanName(
							beanDefinition, this.readerContext.getRegistry(), true);
				}
				else {
					beanName = this.readerContext.generateBeanName(beanDefinition);
					// Register an alias for the plain bean class name, if still possible,
					// if the generator returned the class name plus a suffix.
					// This is expected for Spring 1.2/2.0 backwards compatibility.
					String beanClassName = beanDefinition.getBeanClassName();
					if (beanClassName != null &&
							beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
							!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
						aliases.add(beanClassName);
					}
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Neither XML 'id' nor 'name' specified - " +
							"using generated bean name [" + beanName + "]");
				}
			}
			catch (Exception ex) {
				error(ex.getMessage(), ele);
				return null;
			}
		}
		String[] aliasesArray = StringUtils.toStringArray(aliases);
		return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
	}

	return null;
}

public AbstractBeanDefinition parseBeanDefinitionElement(
		Element ele, String beanName, BeanDefinition containingBean) {

	this.parseState.push(new BeanEntry(beanName));

	String className = null;
	if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
		className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); // 獲取bean element的class屬性
	}

	try {
		String parent = null;
		if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
			parent = ele.getAttribute(PARENT_ATTRIBUTE);
		}
		// 利用反射例項化bean為GenericBeanDefinition
		AbstractBeanDefinition bd = createBeanDefinition(className, parent);
		
		// 解析Element中對應配置檔案的屬性,set到GenericBeanDefinition中
		parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); 
		bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

		parseMetaElements(ele, bd);
		parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); // 解析Override方法
		parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

		parseConstructorArgElements(ele, bd); // 解析建構函式引數
		parsePropertyElements(ele, bd);
		parseQualifierElements(ele, bd);

		bd.setResource(this.readerContext.getResource());
		bd.setSource(extractSource(ele));

		return bd;
	}
	catch (ClassNotFoundException ex) {
		error("Bean class [" + className + "] not found", ele, ex);
	}
	catch (NoClassDefFoundError err) {
		error("Class that bean class [" + className + "] depends on not found", ele, err);
	}
	catch (Throwable ex) {
		error("Unexpected failure during bean definition parsing", ele, ex);
	}
	finally {
		this.parseState.pop();
	}

	return null;
}

// 利用反射例項化GenericBeanDefinition
protected AbstractBeanDefinition createBeanDefinition(String className, String parentName)
		throws ClassNotFoundException {

	return BeanDefinitionReaderUtils.createBeanDefinition(
			parentName, className, this.readerContext.getBeanClassLoader());
}
	
// 解析Element對應的配置檔案屬性,設定到GenericBeanDefinition
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
		BeanDefinition containingBean, AbstractBeanDefinition bd) {

	if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
		// Spring 2.x "scope" attribute
		bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
		if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
			error("Specify either 'scope' or 'singleton', not both", ele);
		}
	}
	else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
		// Spring 1.x "singleton" attribute
		bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ?
				BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
	}
	else if (containingBean != null) {
		// Take default from containing bean in case of an inner bean definition.
		bd.setScope(containingBean.getScope());
	}

	if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
		bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
	}

	String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
	if (DEFAULT_VALUE.equals(lazyInit)) {
		lazyInit = this.defaults.getLazyInit();
	}
	bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

	String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
	bd.setAutowireMode(getAutowireMode(autowire));

	String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
	bd.setDependencyCheck(getDependencyCheck(dependencyCheck));

	if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
		String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
		bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
	}

	String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
	if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
		String candidatePattern = this.defaults.getAutowireCandidates();
		if (candidatePattern != null) {
			String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
			bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
		}
	}
	else {
		bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
	}

	if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
		bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
	}

	if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
		String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
		if (!"".equals(initMethodName)) {
			bd.setInitMethodName(initMethodName);
		}
	}
	else {
		if (this.defaults.getInitMethod() != null) {
			bd.setInitMethodName(this.defaults.getInitMethod());
			bd.setEnforceInitMethod(false);
		}
	}

	if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
		String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
		if (!"".equals(destroyMethodName)) {
			bd.setDestroyMethodName(destroyMethodName);
		}
	}
	else {
		if (this.defaults.getDestroyMethod() != null) {
			bd.setDestroyMethodName(this.defaults.getDestroyMethod());
			bd.setEnforceDestroyMethod(false);
		}
	}

	if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
		bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
	}
	if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
		bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
	}

	return bd;
}
解析<alias>:
DefaultBeanDefinitionDocumentReader.java
protected void processAliasRegistration(Element ele) {
	String name = ele.getAttribute(NAME_ATTRIBUTE); // 獲取alias element的name屬性
	String alias = ele.getAttribute(ALIAS_ATTRIBUTE);// 獲取alias element的alias屬性
	boolean valid = true;
	if (!StringUtils.hasText(name)) {
		getReaderContext().error("Name must not be empty", ele);
		valid = false;
	}
	if (!StringUtils.hasText(alias)) {
		getReaderContext().error("Alias must not be empty", ele);
		valid = false;
	}
	if (valid) {
		try {
			// 將alias註冊到DefaultListableBeanFactory的aliasMap屬性中
			getReaderContext().getRegistry().registerAlias(name, alias); 
		}
		catch (Exception ex) {
			getReaderContext().error("Failed to register alias '" + alias +
					"' for bean with name '" + name + "'", ele, ex);
		}
		// 傳送alias註冊的訊息
		getReaderContext().fireAliasRegistered(name, alias, extractSource(ele)); 
	}
}

SimpleAliasRegistry.java
public void registerAlias(String name, String alias) {
	Assert.hasText(name, "'name' must not be empty");
	Assert.hasText(alias, "'alias' must not be empty");
	if (alias.equals(name)) {
		this.aliasMap.remove(alias);
	}
	else {
		if (!allowAliasOverriding()) {
			String registeredName = this.aliasMap.get(alias);
			if (registeredName != null && !registeredName.equals(name)) {
				throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
						name + "': It is already registered for name '" + registeredName + "'.");
			}
		}
		checkForAliasCircle(name, alias);
		this.aliasMap.put(alias, name); // 將alias註冊到aliasMap中
	}
}
解析CustomElement
BeanDefinitionParserDelegate.java
public BeanDefinition parseCustomElement(Element ele) {
	return parseCustomElement(ele, null);
}

public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
	String namespaceUri = getNamespaceURI(ele); // 獲取element的namespaceUri屬性
	// 利用XmlReaderContext的DefaultNamespaceHandlerResolver namespaceHandlerResolver屬性,根據namespaceUri獲取對應的NamespaceHandler
	NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
	if (handler == null) {
		error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
		return null;
	}
	return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}

       這裡以解析<context:component-scan>為例,說明BeanDefinitionParserDelegate是如何parseCustomElement的。

<!-- 掃描註解檔案  -->
<context:component-scan base-package="com.java" />
       首先,確定NamespaceHandler:parseCustomElement根據Element的namespaceURI,確定NamespaceHandler為ContextNamespaceHandler,這樣BeanDefinitionParserDelegate將解析的工作委託給具體Namespace的NamespaceHandler:
public class ContextNamespaceHandler extends NamespaceHandlerSupport {

	public void init() {
		registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
		registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
		registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
		registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
	}

}


        其次,確定BeanDefinitionParser:在<context>的Namespace下,根據具體的標籤"component-scan",確定BeanDefinitionParser為ComponentScanBeanDefinitionParser,這樣NamespaceHandler將解析的工作委託給具體BeanDefinitionParser。ContextNamespaceHandler針對其命名下的"component-scan"、"annotation-config"標籤等對應不同的BeanDefinitionParser,從而完成Element到BeanDefinition的解析工作:



NamespaceHandlerSupport.java:
// NamespaceHandler將解析工作委託給BeanDefinitionParser
public BeanDefinition parse(Element element, ParserContext parserContext) {
	// 將解析工作委託給ComponentScanBeanDefinitionParser
	return findParserForElement(element, parserContext).parse(element, parserContext); 
}

private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
	// 獲取Element對應的localName,該例為"component-scan"
	String localName = parserContext.getDelegate().getLocalName(element); 
	// ContextNamespaceHandler在init方法中註冊了很多BeanDefinitionParser到HashMap<String, BeanDefinitionParser> parsers,這裡從中獲取對應的
	BeanDefinitionParser parser = this.parsers.get(localName);
	if (parser == null) {
		parserContext.getReaderContext().fatal(
				"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
	}
	return parser;
}

ComponentScanBeanDefinitionParser.java
// 解析Element為BeanDefinition,且完成註冊工作
public BeanDefinition parse(Element element, ParserContext parserContext) {
	// 獲取"base-package"屬性
	String[] basePackages = StringUtils.tokenizeToStringArray(element.getAttribute(BASE_PACKAGE_ATTRIBUTE),
			ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

	// Actually scan for bean definitions and register them.
	ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element); 
	// 用ClassPathBeanDefinitionScanner掃描"base-package"下的BeanDefinition
	Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages); 
	// 註冊CompositeComponentDefinition
	registerComponents(parserContext.getReaderContext(), beanDefinitions, element); 

	return null;
}

// 建立ClassPathBeanDefinitionScanner物件且進行配置
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
	XmlReaderContext readerContext = parserContext.getReaderContext();

	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.
	ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters);
	scanner.setResourceLoader(readerContext.getResourceLoader());
	scanner.setEnvironment(parserContext.getDelegate().getEnvironment());
	scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
	scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());

	if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
		scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
	}

	try {
		parseBeanNameGenerator(element, scanner);
	}
	catch (Exception ex) {
		readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
	}

	try {
		parseScope(element, scanner);
	}
	catch (Exception ex) {
		readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
	}

	parseTypeFilters(element, scanner, readerContext, parserContext);

	return scanner;
}

protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
	return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters);
}

ClassPathBeanDefinitionScanner.java
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
	Assert.notEmpty(basePackages, "At least one base package must be specified");
	Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
	for (String basePackage : basePackages) {
		// 查詢@Component的Class
		Set<BeanDefinition> candidates = findCandidateComponents(basePackage); 
		for (BeanDefinition candidate : candidates) {
			ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
			candidate.setScope(scopeMetadata.getScopeName());
			String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
			if (candidate instanceof AbstractBeanDefinition) {
				postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
			}
			if (candidate instanceof AnnotatedBeanDefinition) {
				AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
			}
			if (checkCandidate(beanName, candidate)) { // 檢測Annotation bean是否已經有同名的bean在BeanFactory註冊,如果沒有則為true
				BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
				definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
				beanDefinitions.add(definitionHolder);
				// 註冊bean到DefaultListableBeanFactory中
				registerBeanDefinition(definitionHolder, this.registry); 
			}
		}
	}
	return beanDefinitions;
}

ClassPathScanningCandidateComponentProvider.java
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
	Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>();
	try {
		String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
				resolveBasePackage(basePackage) + "/" + this.resourcePattern;
		// 獲取"classpath*:com/java/**/*.class"所有的Resource
		Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
		boolean traceEnabled = logger.isTraceEnabled();
		boolean debugEnabled = logger.isDebugEnabled();
		for (Resource resource : resources) {
			if (traceEnabled) {
				logger.trace("Scanning " + resource);
			}
			if (resource.isReadable()) {
				try {
					MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
					if (isCandidateComponent(metadataReader)) { // 判斷是否是Component
						ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
						sbd.setResource(resource);
						sbd.setSource(resource);
						if (isCandidateComponent(sbd)) { // 判斷sbd isConcrete且isIndependent
							if (debugEnabled) {
								logger.debug("Identified candidate component class: " + resource);
							}
							candidates.add(sbd);
						}
						else {
							if (debugEnabled) {
								logger.debug("Ignored because not a concrete top-level class: " + resource);
							}
						}
					}
					else {
						if (traceEnabled) {
							logger.trace("Ignored because not matching any filter: " + resource);
						}
					}
				}
				catch (Throwable ex) {
					throw new BeanDefinitionStoreException(
							"Failed to read candidate component class: " + resource, ex);
				}
			}
			else {
				if (traceEnabled) {
					logger.trace("Ignored because not readable: " + resource);
				}
			}
		}
	}
	catch (IOException ex) {
		throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
	}
	return candidates;
}