BeanDifinition
- 前言
- 什么是BeanDefinition?
- 为什么要有BeanDefinition?
- BeanDifinition重点源码
- 总结
前言
Spring中的BeanDifinition在Bean的实例化流程中占有着非常重要的角色,如果你不了解BeanDifinition的话,面试或者学习Bean的生命周期的话,如同空中楼阁,应付面试可以,如果你想真的成体系化,这部分内容推荐你仔细阅读。
本文结合自己平时笔记和大牛博客整理得出,例子都是自己手敲验证过的,放心阅读。
什么是BeanDefinition?
这个概念在Spring官网的文档里面介绍的很清楚,参考别人的大致说一下:
SpringIOC容器管理一个或多个Bean,这些Bean通过我们提供给容器配置的元数据被创建出来(比如,在xml的定义),在容器中,这些Bean的定义用BeanDefinition对象来表示,包含以下元数据:
- 全限定类名,通过是Bean的实际实现类;
- Bean行为配置元素,它们说明Bean在容器中的行为(作用域,生命周期回调等);
- Bean执行工作所需要的其他Bean的引用;
- 其他配置信息,比如(管理连接池的bean中,限制池的大小或者使用的连接数量);
大概总结一下,BeanDefinition可以看做是Bean的一个定义或者是一个半成品。
为什么要有BeanDefinition?
为什么要这样去设计呢?还要多此一举再添加一个中间状态,直接把Bean创建出来不就好了吗?
举个不同方式创建Bean的例子就明白为什么BeanDefinition是有必要存在的:
- 普普通通创建一个Java bean:
- Spring创建Bean:
好的,如果你是第一次看到这个spring创建bean的这个图估计有点蒙,没关系。
下面我们了解一下在Spring中Bean的实例化流程(这里只是简单介绍,后面会开专辑说),这里我们拿xml配置为元数据进行分析: - Spring容器在进行初始化时,会将XML配置(或者注解)的信息封装成一个BeanDefinition。
- 所有的BeanDefinition存储到一个名为beanDefinitionMap的Map集合中去。
- Spring框架再对Map进行遍历,使用反射创建Bean实例对象,创建好的Bean对象存储在一个名为SingletonObjects的Map集合中。
- 当调用getBean方法时则最终从该Map集合中取出Bean实例对象返回。
这里我们写一个demo来验证看一下:
1.下图是项目的目录
2.我们在xml文件里写了两个bean:
3.写一个测试test,debug看一下,我:
里面有一个BeanFactory是我们要留意的。
4.我们进去BeanFactory看一看,发现有beanDefinitionMap,SingletonObjects。
beanDefinitionMap里面的内容:
还有key为userService里面的值,这里我们主要看里面的propertyValues:
SingletonObjects里面的内容:
所以综上可以看出,BeanDifinition主要是对Bean的一个封装。
那么我们也看到了BeanDifinition存放在BeanDefinitionMap里面,那这个BeanDefinitionMap在哪里呢?
我们通过旁边的括号可以发现,它是在DefaultListableBeanFactory里面:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
/** Resolver to use for checking if a bean definition is an autowire candidate. */
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
/** Map from dependency type to corresponding autowired value. */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);//在这里我们可以看到,是一个ConcurrentHashMap的类型。
但是我们找不到singletonObjects,它在哪里呢?
我们接着找DefaultListableBeanFactory 的父级…5次左右,找到了:
参考一个图会更明白一些:
BeanDifinition重点源码
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
void setParentName(@Nullable String parentName);
@Nullable
String getParentName();
void setBeanClassName(@Nullable String beanClassName);
@Nullable
String getBeanClassName();
/**
* Override the target scope of this bean, specifying a new scope name.
* @see #SCOPE_SINGLETON
* @see #SCOPE_PROTOTYPE
*/
void setScope(@Nullable String scope);
@Nullable
String getScope();
....等等
我们从源码中也可以到看,BeanDIfinition就是对Bean的一个封装。
总结
BeanDifinition初学时不容易,如果没有一个整体的理解,不太容易明白为什么会有BeanDifinition,以及它对于Bean整个生命周期的影响,后面我们聊到生命周期的时候,还会把它拿出来仔细说一说。