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