上文对Spring IOC容器的核心BeanFactory接口分析发现:在默认Bean工厂DefaultListableBeanFactory中对象不是以Object形成存储,而是以BeanDefinition类封装后存放在并发容器ConcurrentHashMap中的,如下所示:
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
下面来对BeanDefinition接口进行分析。
BeanDefinition
首先来看一幅图,BeanDefinition接口的UML类图关系:
可以看到BeanDefinition接口继承了两个接口,这两个接口均为祖宗级接口。AtributeAccessor位于spring-core包下,定义了属性的操作方式;BeanMetadataElement位于spring-beans包下,定义了获取元数据元素的配置源。其源码如下:
package org.springframework.beans.factory.config;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor;
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(String parentName);
String getParentName();
void setBeanClassName(String beanClassName);
String getBeanClassName();
void setScope(String scope);
String getScope();
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
void setDependsOn(String... dependsOn);
String[] getDependsOn();
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
void setPrimary(boolean primary);
boolean isPrimary();
void setFactoryBeanName(String factoryBeanName);
String getFactoryBeanName();
void setFactoryMethodName(String factoryMethodName);
String getFactoryMethodName();
ConstructorArgumentValues getConstructorArgumentValues();
MutablePropertyValues getPropertyValues();
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
int getRole();
String getDescription();
String getResourceDescription();
BeanDefinition getOriginatingBeanDefinition();
}
考虑到篇幅限制,将源码中注释部分去掉。从接口名字即可大致知道该接口实现了哪些功能。
-
setParentName(String parentName)
,getParentName()
可以设置获取该bean的父类bean -
setBeanClassName(String beanClassName)
,getBeanClassName()
可以设置获取该bean的别名 -
setLazyInit(boolean lazyInit)
读取配置文件,设置该bean是否延迟加载;isLazyInit()
判断该bean是否延迟加载 -
setDependsOn(String... dependsOn)
设置bean的依赖项,String[] getDependsOn()
获取依赖项 -
setFactoryBeanName(String factoryBeanName)
设置该bean的加载工厂,String getFactoryBeanName()
获取bean的加载工厂
通过对接口方法分析,可以发现BeanDefinition定义了bean实例的基础方法,基本上通过BeanDefinition接口就可以描述一个bean对象。也即表面在beanDefinitionMap
中BeanDefinition接口可以替代Object对象存储bean实例。
既然两者都可以存储bean对象,为啥是用BeanDefinition而不是Object呢?其实细究可以发现:在Spring中,我们可以自定义是否延迟加载bean对象,合适初始化对象,要想实现加载、初始化时机控制,简单的通过Object对象是无法实现的,必须在此基础上有一个封装,这样才可以实现更多的自定义性质。所以在beanDefinitionMap
中bean对象是以BeanDefinition形式存储。
本文介绍了Spring IOC容器中一个非常重要的接口BeanDefinition,以及解释了为啥beanDefinitionMap
中存储的是BeanDefinition。下文将进入Spring IOC类加载的具体过程,重点看看默认的bean工厂DefaultListableBeanFactory