提到Spring,总是让人第一时间想起IOC容器,而IOC容器的顶层核心接口就是我们的BeanFactory,如果能够理解BeanFactory的体系结构想必能让我们对Spring整体脉络有更加清晰的认知,所以,本文的探究方向主要为以下几点:
我们先来看看有哪些子类实现了它吧

其中ApplicationContext这一块已在上篇文章有详细说明,而
DefaultListableBeanFactory这个底层实现类便理所当然的成为了我们此次探究的出发点,为了让 我们有个更好的观感,以下是纯粹的BeanFactoryUML图:

我们可以看到
DefaultListableBeanFactory实现的接口有:
如果说以上的接口体现了
DefaultListableBeanFactory具备的功能,那么它所继承的一系列类就是这些功能的实现:
> 看到这里,想必对
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);
我们现在已经知道
DefaultListableBeanFactory的大致功能了,我们发现当我们想要创建一个Bean的时候,总是离不开一个名词:Bean定义,那么这个Bean定义究竟是什么呢?
BeanDefinition其实是一个接口,并不是一个具体的类,我们也可以看一下它的UML图:

可以发现这里使用了模板方法的设计模式扩展了许多的子类,其中我们最常用的为RootBeanDefinition,它主要包含的属性如下:

我们向容器中注册的Bean定义的信息大概就是如此,当BeanFactory生产Bean时,便可以通过beanClass清楚的知道Bean的类是什么,作用域是怎样,是否懒加载,init方法是什么等等等等
> 咦,如果一个最简单的bean,好像可以直接通过反射就搞定了耶~
具体结构已经清楚了,那我们来看一下注册过程吧
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 {}
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;}
//除去校验逻辑,注册时只做了这两步操作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[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {//.......代码 //处理普通的bean定义注解,@Lazy @Primary @DependsOn @Role @Description AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); //......代码 }
而非配置的Bean是通过在预启动时注册的配置类后置处理器
ConfigurationClassPostProcessor#processConfigBeanDefinitions中完成的,以下代码为
ClassPathBeanDefinitionScanner#doScan中的摘要部分,详细调用链将在后面的文章进行说明
//传入我们配置类的包路径protected Set doScan(String... basePackages) {Set beanDefinitions = new LinkedHashSet<>();for (String basePackage : basePackages) { //寻找到所有标识了@Component注解的BeanDefinitionSet candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {//....省略代码if (candidate instanceof AbstractBeanDefinition) { //处理BeanDefinitionpostProcessBeanDefinition((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 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)
现在,我们已经知道了一个BeanDefinition的具体结构以及是如何产生并注册到BeanFactory的,那么BeanFactory又是如何使用它生产Bean的呢?以下附上createBean的粗略流程图,具体细节将放在IOC容器启动流程中详细说明

> 那么关于BeanFactory的相关内容就到这里了,希望大家有所收获,下篇将正式进入Spring IOC容器的启动流程!