美文网首页
Spring Bean 基础

Spring Bean 基础

作者: Tinyspot | 来源:发表于2022-07-09 09:03 被阅读0次

1. Bean 类型

  • 普通 Bean
  • 工厂 Bean

1.1 Spring bean VS Java bean

  • Spring bean 有一个初始化的过程,经历过完整 Spring 生命周期,放在spring 容器里
  • Java bean 是 new 出来的对象

1.2 回调注入

  • Aware 接口
  • ApplicationContextAware

ApplicationContextAware

  • 回调注入 ApplicationContext

2. Spring bean 的生命周期

  • Spring 会将 class 信息封装成 BeanDefinition,然后再放进 DefaultListableBeanFactory 的beanDefinitionMap中

2.1 BeanDefinition

  • BeanDefinition 是一种配置元信息,它描述了 Bean 的定义信息
  • interface BeanDefinition extends AttributeAccessor, BeanMetadataElement
  • AbstractBeanDefinition 的三个子类
    • GenericBeanDefinition
    • RootBeanDefinition
    • ChildBeanDefinition

源码分析

  • 入口 obtainFreshBeanFactory()
  • refreshBeanFactory()
  • loadBeanDefinitions(beanFactory);
  • loadBeanDefinitions(beanDefinitionReader);
  • doLoadBeanDefinitions(inputSource, encodedResource.getResource());
  • registerBeanDefinitions(doc, resource);
  • doRegisterBeanDefinitions(doc.getDocumentElement());
  • parseBeanDefinitions(root, this.delegate);
  • parseDefaultElement(ele, delegate);
  • processBeanDefinition(ele, delegate);
  • delegate.parseBeanDefinitionElement(ele);
  • registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())
  • 扫描生成 BeanDefinition ClassPathBeanDefinitionScanner.doScan

2.1 registerBeanDefinitions()

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    // 委托模式,委托 BeanDefinitionDocumentReader 进行 document 解析
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    int countBefore = getRegistry().getBeanDefinitionCount();
    // 具体解析过程
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    return getRegistry().getBeanDefinitionCount() - countBefore;
}

2.2 parseBeanDefinitions()

// DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
if (node instanceof Element) {
    Element ele = (Element) node;
    if (delegate.isDefaultNamespace(ele)) {
        // 3.1 默认标签解析
        parseDefaultElement(ele, delegate);
    } else { 
        // 3.2 自定义标签解析
        delegate.parseCustomElement(ele);
    }
}

3.1 默认标签解析

  • <bean id="" class="" />
  • DefaultBeanDefinitionDocumentReader#parseDefaultElement
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    }
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        doRegisterBeanDefinitions(ele);
    }
}
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
  // 4.1
  BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
  // 4.2 
  BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}

// Bean 属性解析
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
ele.hasAttribute(CLASS_ATTRIBUTE)
ele.hasAttribute(PARENT_ATTRIBUTE)
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
ele.hasAttribute(SINGLETON_ATTRIBUTE)
ele.hasAttribute(SCOPE_ATTRIBUTE)
ele.hasAttribute(INIT_METHOD_ATTRIBUTE)

// BeanDefinitionReaderUtils.registerBeanDefinition()
// DefaultListableBeanFactory 待定...
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

3.2 自定义标签解析

  • <context:component-scan base-package="com..." use-default-filters="true" />
  • 扫描包中的带有 @Component 的类
  • ContextNamespaceHandler#parse (父类 NamespaceHandlerSupport)
  • ComponentScanBeanDefinitionParser#parse
public BeanDefinition parse(Element element, ParserContext parserContext) {
    // base-package
    String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
    basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
    String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
    // 5.1 注解扫描器
    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
    // 5.2 扫描并把类封装成 BeanDefinition 对象
    Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
    // 5.3
    registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
    return null;
}

5.1 configureScanner()

protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
    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);
}
// 注解类型的过滤
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
            Environment environment, @Nullable ResourceLoader resourceLoader) {
    if (useDefaultFilters) {
        registerDefaultFilters();
    }
}

private final List<TypeFilter> includeFilters = new ArrayList<>();
this.includeFilters.add(new AnnotationTypeFilter(Component.class));

5.2 doScan()

  1. 扫描基本包的路径,找 .class 文件
  2. 递归找 .class 文件
  3. 判断 .class 文件里是否有注解,includeFilter 里的@Component
  4. 变成 BeanDefinition 对象

相关文章

网友评论

      本文标题:Spring Bean 基础

      本文链接:https://www.haomeiwen.com/subject/weepvrtx.html