关于spring:Spring的BeanFactory是什么

33次阅读

共计 8007 个字符,预计需要花费 21 分钟才能阅读完成。

什么是 BeanFactory?

提到 Spring,总是让人第一工夫想起 IOC 容器,而 IOC 容器的顶层外围接口就是咱们的 BeanFactory,如果可能了解BeanFactory 的体系结构想必能让咱们对 Spring 整体脉络有更加清晰的认知,所以,本文的探索方向次要为以下几点:

  • BeanFactory的体系结构是怎么的?
  • Bean的元信息从何而来?
  • BeanFactory生产 Bean 的过程是怎么的?

    BeanFactory 的体系结构

咱们先来看看有哪些子类实现了它吧


其中 ApplicationContext 这一块已在上篇文章有具体阐明,而 DefaultListableBeanFactory 这个底层实现类便天经地义的成为了咱们此次探索的出发点,为了让咱们有个更好的观感,以下是纯正的BeanFactoryUML 图:


咱们能够看到 DefaultListableBeanFactory 实现的接口有:

  • SingletonBeanRegistry: 定义了对单例缓存池相干的操作,如将 bean 注册到单例缓存池中
  • ConfigurableBeanFactory: 可配置的BeanFactory,定义了各种各样的配置能力,如 bean 的作用域,bean 的 classLoader, 增加 bean 的后置处理器,设置 bean 的创立状态,销毁 bean 等等
  • AutowireCapableBeanFactory: 能进行主动拆卸的BeanFactory, 这可能是咱们最为相熟的BeanFactory,定义了主动拆卸的类型(byName/byType),createBean, autowireBean, 主动拆卸属性, populateBean, initializeBean, 对于与 bean 生命周期相干的办法都将在这里体现
  • ListableBeanFactory: 对 BeanFactory 的加强,定义了一系列依据 beanType 获取 bean 或者 beanName 的办法
  • ConfigurableListableBeanFactory: 对 ConfigurableBeanFactory 的加强,定义了疏忽 bean 的类型、缓存 bean 定义、预实例化单例 bean 等办法
  • BeanDefinitionRegistry: bean 定义注册器,定义了与 bean 定义相干的办法

如果说以上的接口体现了 DefaultListableBeanFactory 具备的性能,那么它所继承的一系列类就是这些性能的实现:

  • DefaultSingletonBeanRegistry: 单例 bean 注册器,定义了三级缓存,其实就是三个 Map 属性
  • FactoryBeanRegistrySupport: 提供对 FactoryBean 的反对
  • AbstractBeanFactory: 实现了一系列操作 IOC 容器的性能,但最终的 createBean 仍旧交由子类 AbstractAutowireCapableBeanFactory 实现
  • AbstractAutowireCapableBeanFactory: 实现了创立 bean 的性能,所有与创立 bean 的相干的性能都在这里
  • DefaultListableBeanFactory: 在以上父类的性能根底上实现了 ConfigurableBeanFactoryBeanDefinitionRegistry接口,定义了一些寄存 Bean 定义相干信息的 Map

看到这里,想必对 DefaultListableBeanFactory 曾经有一个大抵的理解了,那么问题来啦,咱们应该怎么从容器中获取一个 bean 呢?是不是只有通过 BeanDefinitionRegistry 注册一个 bean 定义,再通过 AutowireCapableBeanFactory 去 createBean 就实现了呢?就像上面这样:

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
RootBeanDefinition beanDefinition = new RootBeanDefinition(Wheel.class);
beanFactory.registerBeanDefinition("wheel",beanDefinition);
beanFactory.getBean("wheel", Wheel.class);

Bean的元信息从何而来?

咱们当初曾经晓得 DefaultListableBeanFactory 的大抵性能了,咱们发现当咱们想要创立一个 Bean 的时候,总是离不开一个名词:Bean 定义,那么这个 Bean 定义到底是什么呢?

BeanDefinition其实是一个接口,并不是一个具体的类,咱们也能够看一下它的 UML 图:


能够发现这里应用了模板办法的设计模式扩大了许多的子类,其中咱们最罕用的为RootBeanDefinition,它次要蕴含的属性如下:

咱们向容器中注册的 Bean 定义的信息大略就是如此,当 BeanFactory 生产 Bean 时,便能够通过 beanClass 分明的晓得 Bean 的类是什么,作用域是怎么,是否懒加载,init 办法是什么等等等等

咦,如果一个最简略的 bean,如同能够间接通过反射就搞定了耶~

具体构造曾经分明了,那咱们来看一下注册过程吧

先从 Demo 看起

public static void main(String[] args) {
    // 创立一个 DefaultListableBeanFactory 实例
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    // 创立一个 BeanDefinition
    RootBeanDefinition beanDefinition = new RootBeanDefinition(Wheel.class);
    // 将 BeanDefinition 注册到容器中
    beanFactory.registerBeanDefinition("wheel",beanDefinition);
}

public static class Wheel {}

创立 BeanDefinition

public RootBeanDefinition(@Nullable Class<?> beanClass) {
    // 初始化父类
    super();
    // 将 beanClass 赋值给 this.BeanClass
    setBeanClass(beanClass);
}

初始化父类

// 将其中一部分属性赋予默认值
autowireCandidate = true;
primary = false;

protected AbstractBeanDefinition() {this(null, null);
}
protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) {
    this.constructorArgumentValues = cargs;
    this.propertyValues = pvs;
}

将 BeanDefinition 注册到容器中

// 除去校验逻辑,注册时只做了这两步操作
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);

看到这里,大家伙可能会充斥疑难?what? 就这样?没有填充属性的步骤吗?嘿嘿,BeanFactory是一个纯正的工厂,只负责生产 Bean,是没有拆卸(设计)BeanDefinition 的性能的,业余的事还是交给业余的人做,设计的事件还是交由 ApplicationContext 实现的。

那在 ApplicationContext 中是怎么实现一个 BeanDefinition 的呢?还记得预启动将配置类注册到容器中时有这样一段代码吗?以下代码为 AnnotatedBeanDefinitionReader#doRegisterBean 中的摘要局部:

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
                        @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
    //....... 代码
    // 解决一般的 bean 定义注解,@Lazy @Primary @DependsOn @Role @Description
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    //...... 代码
   
} 

而非配置的 Bean 是通过在预启动时注册的配置类后置处理器 ConfigurationClassPostProcessor#processConfigBeanDefinitions 中实现的,以下代码为 ClassPathBeanDefinitionScanner#doScan 中的摘要局部,具体调用链将在前面的文章进行阐明

// 传入咱们配置类的包门路
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
        for (String basePackage : basePackages) {
            // 寻找到所有标识了 @Component 注解的 BeanDefinition
            Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
            for (BeanDefinition candidate : candidates) {
                //.... 省略代码
                if (candidate instanceof AbstractBeanDefinition) {
                    // 解决 BeanDefinition
                    postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
                }
                if (candidate instanceof AnnotatedBeanDefinition) {
 // 解决一般的 bean 定义注解,@Lazy @Primary @DependsOn @Role @Description
                    AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
                }
                //... 省略代码
                // 将 BeanDefinition 注册到容器中
                registerBeanDefinition(definitionHolder, this.registry);
            }
    }

解决 BeanDefinition

protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
    // 设置默认值
    beanDefinition.applyDefaults(this.beanDefinitionDefaults);
    // 这里默认为空
    if (this.autowireCandidatePatterns != null) {beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
    }
}

设置默认值

public void applyDefaults(BeanDefinitionDefaults defaults) {
    // 默认为 null
    Boolean lazyInit = defaults.getLazyInit();
    if (lazyInit != null) {setLazyInit(lazyInit);
    }
    // 默认为 0
    setAutowireMode(defaults.getAutowireMode());
    // 默认为 0
    setDependencyCheck(defaults.getDependencyCheck());
    // 默认为 null
    setInitMethodName(defaults.getInitMethodName());
    setEnforceInitMethod(false);
    // 默认为 null
    setDestroyMethodName(defaults.getDestroyMethodName());
    setEnforceDestroyMethod(false);
}

解决一般的 bean 定义注解

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

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
        // 从元数据中取出该注解的属性列表,不为空阐明有标识该注解
        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"));
            }
        }
        // 判断元数据中是否有该注解
        if (metadata.isAnnotated(Primary.class.getName())) {abd.setPrimary(true);
        }
        AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
        if (dependsOn != null) {abd.setDependsOn(dependsOn.getStringArray("value"));
        }
        AnnotationAttributes role = attributesFor(metadata, Role.class);
        if (role != null) {abd.setRole(role.getNumber("value").intValue());
        }
        AnnotationAttributes description = attributesFor(metadata, Description.class);
        if (description != null) {abd.setDescription(description.getString("value"));
        }
    }

attributesFor(metadata, Lazy.class)

static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, Class<?> annotationClass) {return attributesFor(metadata, annotationClass.getName());
}
static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annotationClassName) {
    //metadata 为 beanClass 的注解元数据,寄存了该类所配置的所有注解
    //annotationClassName 为须要寻找的注解名称
    return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName, false));
}
default Map<String, Object> getAnnotationAttributes(String annotationName,
                                                    boolean classValuesAsString) {
    // 遍历元数据中的所有注解
    MergedAnnotation<Annotation> annotation = getAnnotations().get(annotationName,
                                                                   null, MergedAnnotationSelectors.firstDirectlyDeclared());
    // 不存在则返回 null, 否则返回一个 map
    if (!annotation.isPresent()) {return null;}
    return annotation.asAnnotationAttributes(Adapt.values(classValuesAsString, true));
}

以上为扫描 @Component 注解类进行解析元数据填充属性的逻辑,在配置类中以 @Bean 形式注册的 BeanDefinition 填充属性过程在 ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(configClasses)

BeanFactory生产 Bean 的过程是怎么的?

当初,咱们曾经晓得了一个 BeanDefinition 的具体构造以及是如何产生并注册到 BeanFactory 的,那么 BeanFactory 又是如何应用它生产 Bean 的呢?以下附上 createBean 的粗略流程图,具体细节将放在 IOC 容器启动流程中具体阐明

那么对于 BeanFactory 的相干内容就到这里了,心愿大家有所播种,下篇将正式进入 Spring IOC 容器的启动流程!

筹备花个 30 天工夫,零碎的来整顿一下我对 spring 源码的意识:

Spring 源码系列
  1. Spring 源码剖析之 IOC 容器预启动流程(已完结)
  2. Spring 源码剖析之 BeanFactory 体系结构(已完结)
  3. Spring 源码剖析之 BeanFactoryPostProcessor 调用过程(已完结)
  4. Spring 源码剖析之 Bean 的创立过程
  5. Spring 源码剖析之什么是循环依赖及解决方案
  6. Spring 源码剖析之 AOP 从解析到调用
  7. Spring 源码剖析之事务管理(上),事物治理是 spring 作为容器的一个特点,总结一下他的根本实现与原理吧
  8. Spring 源码剖析之事务管理(下),对于他的底层事物隔离与事物流传原理,重点剖析一下
Spring Mvc 源码系列
  1. SpringMvc 体系结构
  2. SpringMvc 源码剖析之 Handler 解析过程
  3. SpringMvc 源码剖析之申请链过程
Mybatis 源码系列

暂定


追更,可关注我,近期有工夫就文章全写完,分享纯正为了乐趣,也有一种成就感吧,笔者这篇文章先就到这

正文完
 0