1.扫描包路径下所有的类加载解析成bean定义信息
ClassPathBeanDefinitionScanner .doScan方法调用路径
doScan:276, ClassPathBeanDefinitionScanner (org.springframework.context.annotation)
parse:95, ComponentScanBeanDefinitionParser (org.springframework.context.annotation)
parse:76, NamespaceHandlerSupport (org.springframework.beans.factory.xml)
parseCustomElement:1475, BeanDefinitionParserDelegate (org.springframework.beans.factory.xml)
parseCustomElement:1452, BeanDefinitionParserDelegate (org.springframework.beans.factory.xml)
parseBeanDefinitions:181, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
doRegisterBeanDefinitions:150, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
registerBeanDefinitions:97, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml)
registerBeanDefinitions:526, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
doLoadBeanDefinitions:397, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
loadBeanDefinitions:341, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
loadBeanDefinitions:310, XmlBeanDefinitionReader (org.springframework.beans.factory.xml)
loadBeanDefinitions:190, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:234, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:197, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:267, AbstractBeanDefinitionReader (org.springframework.beans.factory.support)
loadBeanDefinitions:150, AbstractXmlApplicationContext (org.springframework.context.support)
loadBeanDefinitions:102, AbstractXmlApplicationContext (org.springframework.context.support)
refreshBeanFactory:138, AbstractRefreshableApplicationContext (org.springframework.context.support)
obtainFreshBeanFactory:718, AbstractApplicationContext (org.springframework.context.support)
refresh:577, AbstractApplicationContext (org.springframework.context.support)
<init>:150, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:98, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:15, MyClassPathXmlApplicationContext (com.mashibing)
main:84, Test (com.mashibing)
parse:95, ComponentScanBeanDefinitionParser (org.springframework.context.annotation)
解析节点使用scanner在执行的basePackages包中执行扫描,返回已注册的bean定义
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 获取<context:component-scan>节点的base-package属性值
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);//base-package
// 解析占位符
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
// 解析base-package(允许通过,;\t\n中的任一符号填写多个)
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
// Actually scan for bean definitions and register them.
// 构建和配置ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);//类路径Bean定义扫描器
// 使用scanner在执行的basePackages包中执行扫描,返回已注册的bean定义
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
// 组件注册(包括注册一些内部的注解后置处理器,触发注册事件)
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
doScan:276, ClassPathBeanDefinitionScanner (org.springframework.context.annotation)
扫描开始
/**
* Perform a scan within the specified base packages, 在指定的基本包内执行扫描,
* returning the registered bean definitions. 返回已注册的bean定义。
* <p>This method does <i>not</i> register an annotation config processor 这个方法不注册注释配置处理器
* but rather leaves this up to the caller. 而是把这个问题留给调用者。
* @param basePackages the packages to check for annotated classes 要检查带注释的类的包
* @return set of beans registered if any for tooling registration purposes (never {@code null}) 为了工具注册目的而注册的bean集(从不{@code null})
*/
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) {
// 扫描basePackage,将符合要求的bean定义全部找出来
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
// 遍历所有候选的bean定义
for (BeanDefinition candidate : candidates) {
// 解析@Scope注解,包括scopeName和proxyMode
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
// 使用beanName生成器来生成beanName
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
// 处理beanDefinition对象,例如,此bean是否可以自动装配到其他bean中
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 处理定义在目标类上的通用注解,包括@Lazy,@Primary,@DependsOn,@Role,@Description
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查beanName是否已经注册过,如果注册过,检查是否兼容
if (checkCandidate(beanName, candidate)) {
// 将当前遍历bean的bean定义和beanName封装成BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 根据proxyMode的值,选择是否创建作用域代理
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolde