IOC 核心概念——BeanDefinition
概念
A BeanDefinition describes a bean instance, which has property values,constructor argument values, and further information supplied by concrete implementations.
一个
BeanDefinition描述了一个 Bean 实例,该实例包含属性值、构造方法参数值以及更多实现信息。
BeanDefinition 是 Spring 内部的一个接口,定义了 Bean 描述的基本规范。实际上就是对象在容器中的抽象。通过 BeanDefinition 容器能够方便地对 Bean 进行管理。对于单例的 Bean,在第一次 getBean 的时候读取 BeanDefinition 获取定义,然后再创建和初始化 Bean,并缓存起来。对于原型的 Bean,在每一次 getBean 的时候都需要使用 BeanDefinition 的数据进行创建和初始化,不会缓存 Bean。
BeanDefinition 接口的主要方法覆盖了 Spring 构造 Bean 需要的所有信息:
getBeanClassName:获取 Bean 的类名称;isLazyInit:是否懒加载;getFactoryBeanName:获取对应的 FactoryBean 的名称;getConstructorArgumentValues:获取构造器参数,可以通过 xml、注解注入;getPropertyValues:获取属性参数,可以通过 xml、注解注入。- ............
继承体系
BeanDefinition 是一个接口,它有多个实现类,这些实现类分别描述不同类型的 Bean。

注册 BeanDifinition
将定义 bean 的资源文件解析成 BeanDefinition 后需要将其注入容器中,这个过程由 BeanDefinitionRegistry 来完成。
BeanDefinitionRegistry:向注册表中注册 BeanDefinition 实例,完成注册的过程。
BeanDefinitionRegistry是 Spring 的 Bean 工厂包中唯一封装BeanDefinition注册的接口
BeanDefinitionRegistry 是一个定义了一系列对 BeanDefinition 的操作的接口,如注册、移除、返回等等,需要各子类实现 BeanDefinition 注册的动作,通常由 BeanFactory 实现。
public interface BeanDefinitionRegistry extends AliasRegistry {
/**
* Register a new bean definition with this registry.
* Must support RootBeanDefinition and ChildBeanDefinition.
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
/**
* Remove the BeanDefinition for the given name.
*/
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* Return the BeanDefinition for the given bean name.
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* Check if this registry contains a bean definition with the given name.
*/
boolean containsBeanDefinition(String beanName);
/**
* Return the names of all beans defined in this registry.
*/
String[] getBeanDefinitionNames();
/**
* Return the number of beans defined in the registry.
*/
int getBeanDefinitionCount();
/**
* Determine whether the given bean name is already in use within this registry,
* i.e. whether there is a local bean or alias registered under this name.
*/
boolean isBeanNameInUse(String beanName);
}
继承体系
BeanDefinitionRegistry 继承了 AliasRegistry 接口,其核心子类有三个:SimpleBeanDefinitionRegistry、DefaultListableBeanFactory、GenericApplicationContext。

AliasRegistry
用于别名管理的通用型接口,作为 BeanDefinitionRegistry 的顶层接口。 AliasRegistry 定义了一些别名管理的方法。
public interface AliasRegistry {
/**
* Given a name, register an alias for it.
*/
void registerAlias(String name, String alias);
/**
* Remove the specified alias from this registry.
*/
void removeAlias(String alias);
/**
* Determine whether this given name is defines as an alias
*/
boolean isAlias(String name);
/**
* Return the aliases for the given name, if defined.
*/
String[] getAliases(String name);
}
SimpleBeanDefinitionRegistry
SimpleBeanDefinitionRegistry 是 BeanDefinitionRegistry 一个简单的实现,它还继承 SimpleAliasRegistry( AliasRegistry 的简单实现),它仅仅只提供注册表功能,无工厂功能 。
SimpleBeanDefinitionRegistry 使用 ConcurrentHashMap 来存储注册的 BeanDefinition。
public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// ......
this.beanDefinitionMap.put(beanName, beanDefinition);
}
// ......
}
DefaultListableBeanFactory
DefaultListableBeanFactory 是一个基于 BeanDefinition 元数据的完整 bean 工厂 。所以相对于 SimpleBeanDefinitionRegistry 而言,DefaultListableBeanFactory 则是一个具有注册功能的完整 bean 工厂。它同样是用 ConcurrentHashMap 数据结构来存储注册的 BeanDefinition。
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// ......
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
// 关注这一行代码就行了
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
// 关注这一行代码就行了
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
// ......
}
GenericApplicationContext
对于 GenericApplicationContext ,其实现注册、注销功能都是委托 给 DefaultListableBeanFactory 实现的。
private final DefaultListableBeanFactory beanFactory;
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
转载自:https://juejin.cn/post/7077806547643924517