什么是 BeanFactory?
提到 Spring,总是让人第一工夫想起 IOC 容器,而 IOC 容器的顶层外围接口就是咱们的 BeanFactory
,如果可能了解BeanFactory
的体系结构想必能让咱们对 Spring 整体脉络有更加清晰的认知,所以,本文的探索方向次要为以下几点:
BeanFactory
的体系结构是怎么的?Bean
的元信息从何而来?-
BeanFactory
生产Bean
的过程是怎么的?BeanFactory 的体系结构
咱们先来看看有哪些子类实现了它吧
其中 ApplicationContext
这一块已在上篇文章有具体阐明,而 DefaultListableBeanFactory
这个底层实现类便天经地义的成为了咱们此次探索的出发点,为了让咱们有个更好的观感,以下是纯正的BeanFactory
UML 图:
咱们能够看到 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
: 在以上父类的性能根底上实现了ConfigurableBeanFactory
和BeanDefinitionRegistry
接口,定义了一些寄存 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 源码系列
- Spring 源码剖析之 IOC 容器预启动流程(已完结)
- Spring 源码剖析之 BeanFactory 体系结构(已完结)
- Spring 源码剖析之 BeanFactoryPostProcessor 调用过程(已完结)
- Spring 源码剖析之 Bean 的创立过程
- Spring 源码剖析之什么是循环依赖及解决方案
- Spring 源码剖析之 AOP 从解析到调用
- Spring 源码剖析之事务管理(上),事物治理是 spring 作为容器的一个特点,总结一下他的根本实现与原理吧
- Spring 源码剖析之事务管理(下),对于他的底层事物隔离与事物流传原理,重点剖析一下
Spring Mvc 源码系列
- SpringMvc 体系结构
- SpringMvc 源码剖析之 Handler 解析过程
- SpringMvc 源码剖析之申请链过程
Mybatis 源码系列
暂定
追更,可关注我,近期有工夫就文章全写完,分享纯正为了乐趣,也有一种成就感吧,笔者这篇文章先就到这