Spring IOC源码:<context:component-scan>源码详解

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Spring IOC源码:<context:component-scan>源码详解

文章目录

Spring源码系列:

前言

正文

方法1:configureScanner

方法2:createScanner

方法3:registerDefaultFilters

方法4:parseTypeFilters

方法5:createTypeFilter

方法6:doScan

方法7:findCandidateComponents

方法8:isCandidateComponent

方法9:isCandidateComponent

方法10:resolveScopeMetadata

方法11:generateBeanName

方法12:postProcessBeanDefinition

方法13:processCommonDefinitionAnnotations

方法14:checkCandidate

方法15:applyScopedProxyMode

方法16:createScopedProxy

方法17:registerBeanDefinition

方法18:registerComponents

方法19:registerAnnotationConfigProcessors

方法20:registerPostProcessor

总结

Spring源码系列:

Spring IOC源码:简单易懂的Spring IOC 思路介绍

Spring IOC源码:核心流程介绍

Spring IOC源码:ApplicationContext刷新前准备工作

Spring IOC源码:obtainFreshBeanFactory 详解(上)

Spring IOC源码:obtainFreshBeanFactory 详解(中)

Spring IOC源码:obtainFreshBeanFactory 详解(下)

Spring IOC源码:<context:component-scan>源码详解

Spring IOC源码:invokeBeanFactoryPostProcessors 后置处理器详解

Spring IOC源码:registerBeanPostProcessors 详解

Spring IOC源码:实例化前的准备工作

Spring IOC源码:finishBeanFactoryInitialization详解

Spring IoC源码:getBean 详解

Spring IoC源码:createBean( 上)

Spring IoC源码:createBean( 中)

Spring IoC源码:createBean( 下)

Spring IoC源码:finishRefresh 完成刷新详解

前言

前面我们讲解了自定义命名空间过程及其如何去创建自定义命名空间解析器、xsd文件等,实现了一个demo。这节学习一下< context:component-scan>标签对包进行扫描。

正文

回到自定义标签解析方法中:

  public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
    //获取命名空间处理器地址
    String namespaceUri = getNamespaceURI(ele);
    if (namespaceUri == null) {
      return null;
    }
    //加载处理器
    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));
  }

进入handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));

  public BeanDefinition parse(Element element, ParserContext parserContext) {
    //根据节点标签查找解析器
    BeanDefinitionParser parser = findParserForElement(element, parserContext);
    return (parser != null ? parser.parse(element, parserContext) : null);
  }

因为我们当前节点标签为,所以查找后的解析器为ComponentScanBeanDefinitionParser。

  public BeanDefinition parse(Element element, ParserContext parserContext) {
    //获取需要扫描的包路径base-package
    String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
    //解析占位符
    basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
    //根据这些“,; \t\n”符号进行切割;如:com.zdc.project1;com.zdc.project2   
    String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
        ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
    // 创建配置扫描器
    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
    //扫描带特定配置注解的类,如@component
    Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
    //组件注册(包括注册一些内部的注解后置处理器、触发注册事件)
    registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
    return null;
  }

configureScanner(parserContext, element),见方法1详解

scanner.doScan(basePackages),见方法6详解

registerComponents(parserContext.getReaderContext(), beanDefinitions, element),见方法18详解

方法1:configureScanner

  protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
    //默认配置过滤器,如@Component及其带@Component注解的@Service、@Controller
    boolean useDefaultFilters = true;
    if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
      //如果有配置该属性,则解析获取
      useDefaultFilters = Boolean.parseBoolean(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
    }
    // 创建扫描器
    ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
    //设置Bean默认解析配置
    scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
    //设置自动注入候选模式
    scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
    //设置resource-pattern属性
    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 {
      //解析设置scope-resolver、scoped-proxy属性,scope-resolver、scoped-proxy不能同时存在,反正抛异常
      parseScope(element, scanner);
    }
    catch (Exception ex) {
      parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
    }
    //解析设置过滤器
    parseTypeFilters(element, scanner, parserContext);
    return scanner;
  }

createScanner(parserContext.getReaderContext(),见方法2详解

parseTypeFilters(element, scanner, parserContext),见方法4详解

方法2: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) {
      registerDefaultFilters();
    }
    setEnvironment(environment);
    setResourceLoader(resourceLoader);
  }


registerDefaultFilters(),见方法3详解

方法3:registerDefaultFilters

  protected void registerDefaultFilters() {
    //添加@Component注解类型
    this.includeFilters.add(new AnnotationTypeFilter(Component.class));
    ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
    try {
      //添加ManagedBean注解类型
      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 {
      //添加Named注解类型
      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.
    }
  }

方法4:parseTypeFilters

protected void parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext) {
    // Parse exclude and include filter elements.
    ClassLoader classLoader = scanner.getResourceLoader().getClassLoader();
    //获取子节点标签列表
    NodeList nodeList = element.getChildNodes();
    for (int i = 0; i < nodeList.getLength(); i++) {
      Node node = nodeList.item(i);
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        //获取节点标签名称
        String localName = parserContext.getDelegate().getLocalName(node);
        try {
          //如果为<context:include-filter>
          if (INCLUDE_FILTER_ELEMENT.equals(localName)) {
            //解析节点属性信息
            TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
            scanner.addIncludeFilter(typeFilter);
          }
          //如果为<context:exclude-filter>
          else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) {
            //解析节点属性信息
            TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
            scanner.addExcludeFilter(typeFilter);
          }
        }
        catch (ClassNotFoundException ex) {
          parserContext.getReaderContext().warning(
              "Ignoring non-present type filter class: " + ex, parserContext.extractSource(element));
        }
        catch (Exception ex) {
          parserContext.getReaderContext().error(
              ex.getMessage(), parserContext.extractSource(element), ex.getCause());
        }
      }
    }
  }

createTypeFilter((Element) node, classLoader, parserContext),见方法5详解

方法5:createTypeFilter

protected TypeFilter createTypeFilter(Element element, @Nullable ClassLoader classLoader,
      ParserContext parserContext) throws ClassNotFoundException {
    //获取type属性值
    String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE);
    //获取expression属性值
    String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE);
    //解析占位符
    expression = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(expression);
    //下面根据不同的类型创建不同的过滤器类
    if ("annotation".equals(filterType)) {
      return new AnnotationTypeFilter((Class<Annotation>) ClassUtils.forName(expression, classLoader));
    }
    else if ("assignable".equals(filterType)) {
      return new AssignableTypeFilter(ClassUtils.forName(expression, classLoader));
    }
    else if ("aspectj".equals(filterType)) {
      return new AspectJTypeFilter(expression, classLoader);
    }
    else if ("regex".equals(filterType)) {
      return new RegexPatternTypeFilter(Pattern.compile(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);
    }
  }

xml配置文件示例如下:

  <context:component-scan base-package="service.scan"
              annotation-config="true"
              name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator"
              resource-pattern="**/*.class"
              scope-resolver="org.springframework.context.annotation.AnnotationScopeMetadataResolver"
              use-default-filters="false">
    <!-- 扫描所有带@Component的类 -->
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
    <!-- assignable是对类或接口进行扫描 -->
    <context:include-filter type="assignable" expression="service.scan.domain.Teacher"/>
    <!-- 注意:在use-default-filters="false"的情况下,exclude-filter是针对include-filter里的内容进行排除 -->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    <context:exclude-filter type="assignable" expression="service.scan.domain.College"/>
    <!-- 通配符排除 -->
    <context:exclude-filter type="regex" expression=".service.*"/>
  </context:component-scan>

方法6: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) {
      //通过解析扫描,经过过滤后的BeanDefinition
      Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
      for (BeanDefinition candidate : candidates) {
        //解析设置Scope元属性信息
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
        candidate.setScope(scopeMetadata.getScopeName());
        //生成bean名称,如果没有名称注解,则使用默认生成,以首字母小写类名为beanName
        String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
        if (candidate instanceof AbstractBeanDefinition) {
          //给当前BeanDefinition设置默认值
          postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
        }
        if (candidate instanceof AnnotatedBeanDefinition) {
          //解析设置一些公共属性值,包括@Lazy, @Primary, @DependsOn, @Role, @Description
          AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
        }
        //检查该类是否注册过,如果注册过看是否兼容
        if (checkCandidate(beanName, candidate)) {
          BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
          definitionHolder =
              AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
          beanDefinitions.add(definitionHolder);
          registerBeanDefinition(definitionHolder, this.registry);
        }
      }
    }
    return beanDefinitions;
  }

findCandidateComponents(basePackage),见方法7

this.scopeMetadataResolver.resolveScopeMetadata(candidate),见方法10详解

this.beanNameGenerator.generateBeanName(candidate, this.registry),见方法11详解

postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName),见方法12详解

AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate),见方法13详解

checkCandidate(beanName, candidate),见方法14详解

AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);,见方法15详解

registerBeanDefinition(definitionHolder, this.registry),将方法17详解

方法7:findCandidateComponents

  public Set<BeanDefinition> findCandidateComponents(String basePackage) {
    //默认componentsIndex 为空,会走下面逻辑
    if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
      return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
    }
    else {
      return scanCandidateComponents(basePackage);
    }
  }

进入 scanCandidateComponents(basePackage)

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
    Set<BeanDefinition> candidates = new LinkedHashSet<>();
    try {
      //拼接查询的包路径,如classpath*:service/scan/**/*.class
      String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
          resolveBasePackage(basePackage) + '/' + this.resourcePattern;
      //解析包下的所有文件资源路径,
      //如file [D:\Code\SourceCode\LeanCode\Spring\spring-framework-5.2.0.RELEASE\learn-test\build\classes\java\main\service\scan\dao\StudentDao.class]
      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 {
            //获取元注解属性
            MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
            //根据过滤器判断进行校验
            if (isCandidateComponent(metadataReader)) {
              //创建ScannedGenericBeanDefinition类用于封装扫描出来类的属性
              ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
              sbd.setResource(resource);
              sbd.setSource(resource);
              // 判断sbd是否为候选类(独立的 && (具体的实现类 || (抽象类 && 类中有方法使用@Lookup注解)))
              if (isCandidateComponent(sbd)) {
                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;
  }

isCandidateComponent(metadataReader),见方法8详解

isCandidateComponent(sbd),见方法9详解

方法8: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) {
      // 如果metadataReader与includeFilters中的任意一个TypeFilter匹配(如果tf为Component注解:metadataReader对应的类使用了Component则匹配),
      if (tf.match(metadataReader, getMetadataReaderFactory())) {
        // 判断是由有@Conditional;如果有,则返回true,表示metadataReader对应的类为候选类
        return isConditionMatch(metadataReader);
      }
    }
    return false;
  }

方法9:isCandidateComponent

  protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
    AnnotationMetadata metadata = beanDefinition.getMetadata();
    // isIndependent:确定底层类是否是独立的,即它是否是顶级类或嵌套类(静态内部类),它可以独立于封闭类构造。
    // isConcrete:返回底层类是表示具体类,即:既不是接口也不是抽象类。
    // isAbstract:返回底层类是否标记为抽象。
    // hasAnnotatedMethods:确定基础类是否具有使用给定注解(@Lookup)类型进行注解(或元注解)的任何方法。
    return (metadata.isIndependent() && (metadata.isConcrete() ||
        (metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
  }

方法10:resolveScopeMetadata

  public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
    //创建ScopeMetadata,默认属性为singleton 单例
    ScopeMetadata metadata = new ScopeMetadata();
    if (definition instanceof AnnotatedBeanDefinition) {
      AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
      //获取Scope属性
      AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
          annDef.getMetadata(), this.scopeAnnotationType);
      if (attributes != null) {
        //不为空,设置Scope属性
        metadata.setScopeName(attributes.getString("value"));
        // 解析proxyMode属性
        ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
        if (proxyMode == ScopedProxyMode.DEFAULT) {
          proxyMode = this.defaultProxyMode;
        }
        metadata.setScopedProxyMode(proxyMode);
      }
    }
    return metadata;
  }

这里会创建ScopeMetadata类,默认Scope属性值为Singleton,解析是否有@Scope注解值,有则解析设置。

方法11:generateBeanName

  @Override
  public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
    if (definition instanceof AnnotatedBeanDefinition) {
      String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
      if (StringUtils.hasText(beanName)) {
        // Explicit bean name found.
        return beanName;
      }
    }
    // 构建默认名称,以类名并且第一个字母小写
    return buildDefaultBeanName(definition, registry);
  }
  /**
   * Derive a bean name from one of the annotations on the class.
   * @param annotatedDef the annotation-aware bean definition
   * @return the bean name, or {@code null} if none is found
   */
  @Nullable
  protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
    //获取元注解信息
    AnnotationMetadata amd = annotatedDef.getMetadata();
    //获取注解类型
    Set<String> types = amd.getAnnotationTypes();
    String beanName = null;
    for (String type : types) {
      //获取value属性
      AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
      //判断是否ManagedBean、Component、Named注解,及其attributes 是否有value属性
      if (attributes != null && isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), 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 new IllegalStateException("Stereotype annotations suggest inconsistent " +
                  "component names: '" + beanName + "' versus '" + strVal + "'");
            }
            beanName = strVal;
          }
        }
      }
    }
    return beanName;
  }

方法12:postProcessBeanDefinition

  protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
    //给当前BeanDefinition设置默认一些配置值,
    beanDefinition.applyDefaults(this.beanDefinitionDefaults);
    if (this.autowireCandidatePatterns != null) {
      //设置AutowireCandidate属性默认为true,代表可以被其它类注入
      beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
    }
  }
  public void applyDefaults(BeanDefinitionDefaults defaults) {
    Boolean lazyInit = defaults.getLazyInit();
    if (lazyInit != null) {
      setLazyInit(lazyInit);
    }
    setAutowireMode(defaults.getAutowireMode());
    setDependencyCheck(defaults.getDependencyCheck());
    setInitMethodName(defaults.getInitMethodName());
    setEnforceInitMethod(false);
    setDestroyMethodName(defaults.getDestroyMethodName());
    setEnforceDestroyMethod(false);
  }

方法13:processCommonDefinitionAnnotations

public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
    processCommonDefinitionAnnotations(abd, abd.getMetadata());
  }
  static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
    //获取@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"));
      }
    }
    //获取设置@Primary,当属性注入有多个时,配置了Primary将作为首先
    if (metadata.isAnnotated(Primary.class.getName())) {
      abd.setPrimary(true);
    }
    //解析设置@DependsOn,设置该类依赖其它类,被依赖类也会被创建管理
    AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
    if (dependsOn != null) {
      abd.setDependsOn(dependsOn.getStringArray("value"));
    }
    //解析设置@Role
    AnnotationAttributes role = attributesFor(metadata, Role.class);
    if (role != null) {
      abd.setRole(role.getNumber("value").intValue());
    }
    //解析设置@Description
    AnnotationAttributes description = attributesFor(metadata, Description.class);
    if (description != null) {
      abd.setDescription(description.getString("value"));
    }
  }

方法14:checkCandidate

protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
    //判断已经注册缓存中是否存在该beanName
    if (!this.registry.containsBeanDefinition(beanName)) {
      return true;
    }
    //获取已存在的BeanDefinition 
    BeanDefinition existingDef = this.registry.getBeanDefinition(beanName);
    //获取原始BeanDefinition ,代理的会有原始值
    BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition();
    if (originatingDef != null) {
      existingDef = originatingDef;
    }
    //检查新BeanDefinition是否与原BeanDefinition兼容,如果兼容则返回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() + "]");
  }


方法15:applyScopedProxyMode

  static BeanDefinitionHolder applyScopedProxyMode(
      ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
    ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
    //如果不代理,则返回原始值
    if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
      return definition;
    }
    //判断代理方式,基于类还是基于接口;基于类:使用Cglib,基于接口:JDK动态代理
    boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
    return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
  }

ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass),见方法16详解

方法16:createScopedProxy

  public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
      BeanDefinitionRegistry registry, boolean proxyTargetClass) {
    //获取原始beanName
    String originalBeanName = definition.getBeanName();
    //获取原始BeanDefinition 
    BeanDefinition targetDefinition = definition.getBeanDefinition();
    //为原始beanName重新生成一个名称,原始BeanName名称加上前缀 scopedTarget.
    String targetBeanName = getTargetBeanName(originalBeanName);
    //使用ScopedProxyFactoryBean作为要创建代理的BeanDefinition
    RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
    // 将原始bean封装成BeanDefinitionHolder,设置到代理的decoratedDefinition属性
    proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
    //设置代理的原始BeanDefinition属性值
    proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
    proxyDefinition.setSource(definition.getSource());
    proxyDefinition.setRole(targetDefinition.getRole());
    //添加类属性,值为新生成的beanName
    proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
    if (proxyTargetClass) {
      //使用Cglib代理方式,设置属性值,ScopedProxyFactoryBean的该属性默认就为true
      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 {
      //使用JDK动态代理方式,设置属性值
      proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
    }
    // Copy autowire settings from original bean definition.
    //拷贝原始对象的信息
    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.
    //原始的Bean不被其它类所注入
    targetDefinition.setAutowireCandidate(false);
    targetDefinition.setPrimary(false);
    // Register the target bean as separate bean in the factory.
    //原始bean注册到缓存中
    registry.registerBeanDefinition(targetBeanName, targetDefinition);
    // Return the scoped proxy definition as primary bean definition
    // (potentially an inner bean).
    //将代理bean封装成BeanDefinitionHolder对象并返回
    return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
  }

方法17:registerBeanDefinition

  protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
  }
  public static void registerBeanDefinition(
      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
      throws BeanDefinitionStoreException {
    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    //往beanDefinitionNames放BeanName,往beanDefinitionMap放 <beanName:BeanDefinitionHolder >
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    // Register aliases for bean name, if any.
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
      //往aliasMap放 <alias:beanName>
      for (String alias : aliases) {
        registry.registerAlias(beanName, alias);
      }
    }
  }

注册过程,我们在解析默认命名空间配置的时候也有讲解到,主要往三个缓存添加beanDefinitionMap、beanDefinitionNames、aliasMap。

方法18:registerComponents

  protected void registerComponents(
      XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
    Object source = readerContext.extractSource(element);
    //获取标签节点名称,并封装成CompositeComponentDefinition 对象
    CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
    //将扫描到的所有BeanDefinition添加到compositeDef的nestedComponents属性中
    for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
      compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
    }
    // Register annotation config processors, if necessary.
    boolean annotationConfig = true;
    //获取annotation-config属性值
    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.registerAnnotationConfigProcessors(readerContext.getRegistry(), source),见方法19详解

方法19:registerAnnotationConfigProcessors

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
      BeanDefinitionRegistry registry, @Nullable Object source) {
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
      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;
  }

registerPostProcessor方法,见方法20详解

方法20:registerPostProcessor

  private static BeanDefinitionHolder registerPostProcessor(
      BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
    //设置默认Role属性
    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    //往beanDefinitionMap、beanDefinitionNames缓存放入
    registry.registerBeanDefinition(beanName, definition);
    //新建包装类
    return new BeanDefinitionHolder(definition, beanName);
  }


到这里 < context:component-scan> 节点解析已经完成了

总结

整个解析过程已经做了一遍了,现在梳理一下流程:

1、获取包路径、对路径进行占位符替换,根据“,;\n\t”解析成路径数组

2、创建扫描器,解析配置过滤器,如果是默认过滤器则include加入默认注解属性,如:Compenent、ManagedBean、Named;以及自定义过滤器属性处理,如:

<context:include-filter type=“assignable” expression=“service.scan.domain.Teacher”/>

<context:exclude-filter type=“assignable” expression=“service.scan.domain.College”/>

3、开始扫描,遍历包路径,拼接通配符,加载包下面的资源,如xxx.class

4、 扫描出类,加载元注解属性,并经过过滤器处理。

5、得到BeanDinifition后,设置公共属性,判断是否需要代理,以及解析代理方法是使用Cglib,还是JDK动态代理

6、注册到上下文缓存中,beanDefinitionMap、beanDefinitionNames、aliasMap。

7、添加了几个内部的注解相关的后置处理器:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor 等。


本章就讲解到这里,整个解析工作告一段落了。后面开始讲解IOC 流程中的后置处理器处理,及其多播器等,最后再进入最核心部分,Bean实例化初始化工作。






目录
相关文章
|
3天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
15 2
|
19天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
9天前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
35 9
|
18天前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
9天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
22 0
|
1月前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
108 5
|
1月前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
30天前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
65 0
|
1月前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
46 0
|
1月前
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
79 0