关于spring:Spring的BeanFactory是什么

什么是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 源码系列

暂定


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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理