本文首发于个人公众号 Java 技术大杂烩,欢迎关注
所谓 bean 的注册,就是把在配置文件中配置的 <bean>
节点加载配内存中,供后续使用。
bean的注册主要分为两个阶段,一个是准备阶段,就是对配置文件进行解析,把配置文件加载到内存中,以 Document
的形式存放;第二个阶段是对 Document
进行操作,获取其中的节点,进行解析,注册。
按照惯例,在看源码之前,先来看看和 bean 注册相关的类图,所涉及到的类比较多,也是挺复杂的,类图如下所示:
先看看每个类的主要实现,最后再根据一个栗子来看 bean 注册的主要流程。
AliasRegistry
:定义了对别名 alias 的简单增删改等操作。SimpleAliasRegistry
: 它是 AliasRegistry 接口的一个实现类,使用 map 来做 alias 的的映射。BeanDefinitionRegistry
:继承 AliasRegistry 接口, 定义了对 BeanDefinition 的各种增删改操作。SingletonBeanRegistry
:定义对单例bean的注册和获取。DefaultSingletonBeanRegistry
:是 SingletonBeanRegistry 接口的实现。FactoryBeanRegistrySupport
:在 DefaultSingletonBeanRegistry 的基础上增加了对 FactoryBean 的特殊处理功能。BeanFactory
:定义了获取bean和bean的各种属性。HierarchicalBeanFactory
: 继承 BeanFactory ,扩展了获取父beanFactory。ConfigurableBeanFactory
:提供了配置 Factory 的各种方法。AbstractBeanFactory
:综合了 FactoryBeanRegistrySupport 和 ConfigurableBeanFactory 的功能。AutowireCapableBeanFactory
:提供创建bean,自动注入,初始化以及应用bean的后置处理器。AbstractAutowireCapableBeanFactory
:综合了 AbstractBeanFactory 并对接口 AutowireCapableBeanFactory 进行实现。ListableBeanFactory
:根据各种条件获取bean的配置清单。ConfigurableListableBeanFactory
:BeanFactory 的配置清单,指定忽略类型及接口。DefaultListableBeanFactory
:综合上述所有的功能,主要是对 bean 注册后的处理。BeanDefinition
是一个接口,它是配置文件 <bean>
标签在 Spring 容器中的内部表现形式,<bean>
标签拥有的属性也会对应于 BeanDefinition
中的属性,它们是一一对应的,即一个 <bean>
标签对应于一个 BeanDefinition
实例。BeanDefinition
相关的类图如下:
共有三个实现类,在配置文件中可以有父bean和子bean,父bean用 RootBeanDefinition
来表示,子bean用 ChildBeanDefinition
来表示,而 GenericBeanDefinition
是一个通用的BeanDefinition
。
AbstractBeanDefinition
实现了BeanDefinition
接口,在 BeanDefinition
接口中只是定义了<bean>
标签对应属性的 setter/getter
方法,而没有定义对应的属性,而在 AbstractBeanDefinition
类中就定义了对应的各种属性,并重写了接口的 setter/getter
方法:
AliasRegistry
定义了对别名 alias 的简单增删改等操作。
SimpleAliasRegistry
它是 AliasRegistry
接口的一个实现类,使用 map 来做 alias 的的映射。
public class SimpleAliasRegistry implements AliasRegistry {
// 映射的 map
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);
// 注册别名
@Override
public void registerAlias(String name, String alias) {
synchronized (this.aliasMap) {
// 如果真实的名字和别名相同,则把别名移除点,因为真实的名字和别名相同没有意义
if (alias.equals(name)) {
this.aliasMap.remove(alias);
}
else {
String registeredName = this.aliasMap.get(alias);
// 如果已经注册过了
if (registeredName != null) {
// 已经注册过了且别名没有发生变化,则不处理,没有必要再注册一次
if (registeredName.equals(name)) {
return;
}
// 如果别名不允许覆盖,则抛出异常
if (!allowAliasOverriding()) {
throw new IllegalStateException("");
}
}
checkForAliasCircle(name, alias);
// 注册别名
this.aliasMap.put(alias, name);
}
}
}
// 其他的方法都是通过 aliasMap 来判断的
}
BeanDefinitionRegistry
继承 AliasRegistry
接口, 定义了对 BeanDefinition
的各种增删改操作。
SingletonBeanRegistry
定义对单例bean的注册和获取。
DefaultSingletonBeanRegistry
是 SingletonBeanRegistry
接口的实现,主要是注册bean。该类中定义了许多的 集合,用于注册
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// 如果bean为null则使用 NULL_OBJECT 来站位
protected static final Object NULL_OBJECT = new Object();
// 单例对象缓存,bean name --> bean instance
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object(256);
// 单例对应的工厂缓存,可以使用工厂来创建单例对象 bean name --> ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String,ObjectFactory<?>>(16);
// 之前的单例对象
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
// 已经注册过了的单例对象
private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
// 当前正在创建的单例对象集合
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
// 需要排除的单例,什么意思呢?在创建单例的时候,如果该单例正在创建,就不会再创建了,就应该排除掉,如果某个单例在该集合中,则表示该单例正在创建
private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
// ..... 其他的集合 .....
// 注册单实例的bean
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
// 加锁:为什么用 ConcurrentHashMap 了还需要加锁?
synchronized (this.singletonObjects) {
// 判断是否已经注册过了,如果注册过了,则抛出异常
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("...");
}
// 注册
addSingleton(beanName, singletonObject);
}
}
// 真正的注册逻辑,就是把bean的名称和对象放到map中
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 注册,如果单例对象为null,则使用 NULL_OBJECT 站位
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
// 该单例对象已经注册成功,则需要从工厂集合中移除,后面不需要再次注册
this.singletonFactories.remove(beanName);
// 之前注册过的对象也移除
this.earlySingletonObjects.remove(beanName);
// 向已经注册的单例集合中添加该实例
this.registeredSingletons.add(beanName);
}
}
// 根据 beanName 获取单例对象
@Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
// allowEarlyReference 参数是为了解决循环引用
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// 如果该单例没有注册过,且正在注册
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 如果之前也没有注册过,且llowEarlyReference=true
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 获取该bean对应的工厂,通过工厂了创建还bean
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
// 创建成功后,需要去除
this.singletonFactories.remove(beanName);
}
}
}
}
// 返回单例对象
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
// 获取所有单例的name
@Override
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
return StringUtils.toStringArray(this.registeredSingletons);
}
}
// 获取所有已经注册了的单例的个数
@Override
public int getSingletonCount() {
synchronized (this.singletonObjects) {
return this.registeredSingletons.size();
}
}
BeanFactory
它是访问 Spring
容器的根接口,定义了获取bean的各种重载方法:
AbstractBeanFactory
,它是 BeanFactory
接口的一个抽象实现类,即 综合了 FactoryBeanRegistrySupport
和 ConfigurableBeanFactory
的功能。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
// bean的后置处理器 BeanPostProcessor 的集合
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
// 当前正在创建的bean的名称集合
private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<Object>("Prototype beans currently in creation");
// 其他属性
// 获取bean
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException{
return doGetBean(name, requiredType, args, false);
}
// 获取bean,比较复杂,后面介绍了bean注册过,在来看
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {
// 后面分析
}
// 其他方法
}
它继承了 AbstractBeanFactory
并对接口 AutowireCapableBeanFactory
进行实现,它提供bean创建,属性填充,自动装配和初始化。 处理运行时bean引用,解析托管集合,调用初始化方法等。此外,它可以按照构造函数,名称和类型来自动装配。
该类后面再分析bean的加载时在分析
在使用 bean 之前,会先注册所有的 bean,注册的 bean 就是以 map 的形式放在该类中。从上面的类图中也可以看到,该类实现了或者说继承了两种不同的接口和抽象类,一种是和注册相关的接口和抽象类,一种是和获取bean相关的接口,现在只关心和bean注册相关的部分:
先来看看它定义的一些属性:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
// 序列化相关
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);
private String serializationId;
// 当有相同名称不同实例时是否允许覆盖,默认允许
private boolean allowBeanDefinitionOverriding = true;
// 对于赖加载的bean,是否允许立即加载
private boolean allowEagerClassLoading = true;
// bean 注册的缓存,注册的bean就放在该集合中
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
// 根据类型来返回所有bean的name,包含单例和原型两种模式的bean
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
// 根据类型返回bean的name,只是返回单例的bean
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
// 注册的bean的name的集合
private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
// 手动注册的单例的 bean name 集合
private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);
// 在冻结配置的情况下缓存bean定义名称数组
private volatile String[] frozenBeanDefinitionNames;
// 是否可以为所有bean缓存bean 的元数据
private volatile boolean configur
接下来看下和bean注册相关的方法:
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition){
if (beanDefinition instanceof AbstractBeanDefinition) {
// 注册前的最后一次检验,主要是对 AbstractBeanDefinition 的属性methodOverrides进行校验
((AbstractBeanDefinition) beanDefinition).validate();
}
BeanDefinition oldBeanDefinition;
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
// 如果已经注册该bean
if (oldBeanDefinition != null) {
// 如果已经注册过该bean,且设置为不允许覆盖,则抛出异常
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException();
}
// 如果允许覆盖,则直接注册,覆盖
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
// 该bean还没注册,检查该工厂的bean创建阶段是否已经开始,即在此期间是否已将该bean标记为已创建。如果已经标记为创建
if (hasBeanCreationStarted()) {
// 无法再修改启动时集合元素(用于稳定迭代)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
// 更新 beanDefinitionNames 这个集合
List<String> updatedDefinitions = new
ArrayList<String(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
// 安全的从 manualSingletonNames 集合中移除该bean
Set<String> updatedSingletons = new LinkedHashSet<String(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// 如果仍然在启动注册阶段,则直接注册
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
}
// 注册单例的bean
@Override
public void registerSingleton(String beanName, Object singletonObject) {
// 调用父类 DefaultSingletonBeanRegistry 的方法进行注册,上面已经分析过
super.registerSingleton(beanName, singletonObject);
// 同样的,如果该bean已经标注为开始创建,
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
if (!this.beanDefinitionMap.containsKey(beanName)) {
// 安全的更新 manualSingletonNames
Set<String> updatedSingletons = new LinkedHashSet<String(this.manualSingletonNames.size() + 1);
updatedSingletons.addAll(this.manualSingletonNames);
updatedSingletons.add(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
//直接注册
if (!this.beanDefinitionMap.containsKey(beanName)) {
this.manualSingletonNames.add(beanName);
}
}
}
下面通过一个栗子再来看看上面涉及到的类,熟悉 bean 注册的一个流程
首先,来看一个 bean 配置的全部属性:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd" >
<bean id="testBean" class="main.tsmyk.pojo.MyTestBean"
abstract="true" autowire="byName" autowire-candidate="true"
depends-on="conversionService" destroy-method="getName"
factory-bean="environment" factory-method=""
init-method="getName" lazy-init="true" name="myTestBean"
parent="environment" primary="true" scope="singleton" >
<property name="name" value=""/>
<constructor-arg name="a" value="a" type="TestBean" index="" ref="">
<bean name="" />
<map key-type="" value-type=""/>
</constructor-arg>
<qualifier value="a" type=""/>
<lookup-method />
<meta key="" value=""/>
<replaced-method/>
</bean>
<alias name="testBean" alias="aaa"/>
<import resource=""/>
</beans>
测试代码:
public static void main(String[] args){
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("myspring.xml"));
MyTestBean testBean = (MyTestBean) beanFactory.getBean("testBean");
System.out.println(testBean.getName());
}
上面也说了,bean的注册主要分为两部分,第一部分加载配置文件到内存形式Document,第二部分对Document的节点进行解析,注册。这部分不过多的介绍,只需要知道配置文件加载到内存形成 Document 就可以了。 解析配置文件的时序图如下所示:
最终,注册 bean 的逻辑是从 DefaultBeanDefinitionDocumentReader
类的 parseBeanDefinitions()
方法开始的,该方法如下所示:
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// 表示的是默认的节点
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
// 解析默认的节点
parseDefaultElement(ele, delegate);
}
else {
// 解析自定义节点
delegate.parseCustomElement(ele);
}
}
}
}
else {
// 解析自定义节点
delegate.parseCustomElement(root);
}
}
在 Spring 的配置文件中,有两大类bean的声明,一个是默认的声明如 <bean>
,一类是自定义的声明如 <tx:annotation-driver>
,所以该方法分为两套解析逻辑。
默认标签的解析对应的是 parseDefaultElement()
方法
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析 <import>
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
// 解析 <alias>
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
// 解析 <bean>
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
// 解析 <beans>
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
doRegisterBeanDefinitions(ele);
}
}
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析 bean的各种属性
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 如果该bean包含自定义的子标签,则对自定义子标签解析
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
// 注册
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
// 发消息,可以忽略
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
解析bean的属性和子节点
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
//containingBean: 父 bean
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
// id 属性
String id = ele.getAttribute(ID_ATTRIBUTE);
// name 属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
// name 属性值就是别名 alias,解析 name 的值,放到 alias 集合中,
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
// 这里可以看到 name 的值可以使用 , ; 和空格进行分割
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
aliases.addAll(Arrays.asList(nameArr));
}
// beanName 的值就是 id 的值
String beanName = id;
// 如果 beanName 为空,且 alias 不为空,则获取第一个别名作为beanName
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
}
// 如果父 bean 为空,则检查beanName的唯一性
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
// 创建 AbstractBeanDefinition 在该方法内部,会解析bean所有的属性和子节点
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
// 如果 beanName为空,则根据spring中的命名规则为该bean生成对应的beanName
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
// 把该bean的类名也注册为别名,为了向后兼容
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
}
// BeanDefinitionHolder 创建对象返回,分别设置对应的属性值
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
// 解析属性和子节点
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean) {
// 不知道干嘛用
this.parseState.push(new BeanEntry(beanName));
// 获取 class 属性的值
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
// 获取 parent 属性的值
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
// 创建 AbstractBeanDefinition 对象,底层是 GenericBeanDefinition
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 解析所有属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// 解析 <meta>
parseMetaElements(ele, bd);
// 解析 <lookup-method />
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// 解析 <replaced-method/>
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 解析 <constructor-arg />
parseConstructorArgElements(ele, bd);
// 解析 <property />
parsePropertyElements(ele, bd);
// 解析 <qualifier />
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
// 解析所有属性
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
BeanDefinition containingBean, AbstractBeanDefinition bd) {
// singleton 和 scope 只能有一个
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
}
else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
}
else if (containingBean != null) {
bd.setScope(containingBean.getScope());
}
// abstract 属性
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
}
// lazyInit 属性
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
// 其他属性
}
// 解析 <meta>
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
// 判断是 meta 节点
if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
Element metaElement = (Element) node;
String key = metaElement.getAttribute(KEY_ATTRIBUTE);
String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
attribute.setSource(extractSource(metaElement));
attributeAccessor.addMetadataAttribute(attribute);
}
}
}
// 其他节点的解析类似
当解析完bean的所有属性和子节点后,得到 BeanDefinitionHolder
对象,该对象中包含了 bean 定义的的全部信息,之后会对该对象进行包装,为什么需要进行包装的?如果配置的bean有子节点,且该子节点是用户自定义的节点,则会对该子节点进行包装:
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) {
return decorateBeanDefinitionIfRequired(ele, definitionHolder, null);
}
// 包装,containingBd:父bean
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd) {
// 最终的 BeanDefinitionHolder
BeanDefinitionHolder finalDefinition = definitionHolder;
// 遍历所有属性,看看否是有适用于修改的属性
NamedNodeMap attributes = ele.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Node node = attributes.item(i);
finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
}
// 遍历所有子节点,看看是否有适用于修改的子节点
NodeList children = ele.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node node = children.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
}
}
return finalDefinition;
}
public BeanDefinitionHolder decorateIfRequired(
Node node, BeanDefinitionHolder originalDef, BeanDefinition containingBd) {
// 获取自定义的命名空间
String namespaceUri = getNamespaceURI(node);
// 不是默认的命名空间,则是自定义的命名空间
if (!isDefaultNamespace(namespaceUri)) {
// 根据命名空间获取对应的处理器
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler != null) {
return handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
}
}
return originalDef;
}
到这里bean的定义解析完毕了,接下来就是把解析后的bean注册到Spring容器中了:
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
// 注册
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
// bean的名字
String beanName = definitionHolder.getBeanName();
// 使用 DefaultListableBeanFactory 来注册bean,即把beanName和对应的BeanDefinition 注册到map中,上面分析DefaultListableBeanFactory 类时已经分析过该方法了
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 注册别名,调用 SimpleAliasRegistry 的 registerAlias 来注册别名,上面已经分析该类了
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
到这里<bean>
标签的注册已经分析完毕了,还剩下<import>
,<alias>
和 <beans>
标签的解析,关于 <alias>
标签的注册,在上述分析 SimpleAliasRegistry
就分析过了,剩下的两个也是同样的套路。
到这里,关于bean的注册就分析完毕了。