当我们通过向Spring容器获取某个bean的时候,总是调用Spring中重载的各种getBean方法。那么,getBean中的流程是什么样的?
通过本文,你将对getBean方法的主流程有一个详细的认识。
入口当然是getBean方法:
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected T doGetBean(
final String name, final Class requiredType, final Object[] args,
boolean typeCheckOnly) throws BeansException {
//beanName转换,这里主要有两方面的考虑:
//1:如果beanName是以&开头的,则表明是要返回FactoryBean本身
//而不是其生产出来的对象,而FactoryBean存储的时候,跟普通的bean一样
//2:如果传入的是别名,则是需要转换为实际的beanName的
final String beanName = transformedBeanName(name);
Object bean;
// 检查bean是否已经存在了缓存中
Object sharedInstance = getSingleton(beanName);
//不为空则表明之前被创建过
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
.............
}
//这里对于普通的bean,则会直接的返回,
//如果是FactoryBean类型的则会创建对应的实例返回
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//如果是正在创建的Prototype类型的bean,无法处理该类型循环依赖的问题,则直接抛出异常信息
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 查看父类中是否有相关的bean的定义信息
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 如果name是以&开头的 则返回&+beanName的格式
String nameToLookup = originalBeanName(name);
if (args != null) {
//递归去父类中查找
return (T) parentBeanFactory.getBean(nameToLookup, args);
}else {
//递归去父类中查找
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//将父类的定义的BeanDefinition与子类的BeanDefinition进行合并覆盖
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//判断bean是否有dependsOn 类的依赖
//如果没有循环依赖,则先创建所dependsOn依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
//这里主要是判断是否有以下这种类型的依赖:
//
//
//如果有,则直接抛出异常
if (isDependent(beanName, dep)) {
.......
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
// 处理完bean的依赖关系,则开始来创建bean
if (mbd.isSingleton()) {
//创建单例的bean,这里的createBean下文将详细讲解
sharedInstance = getSingleton(beanName, new ObjectFactory
整个getBean大的流程如上所示,在以上源码中,我们将看下以下的几个的方法:
1:transformedBeanName方法:
protected String transformedBeanName(String name) {
//如果beanName是以&开头的 则截取掉开头的&
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
public String canonicalName(String name) {
String canonicalName = name;
// 循环的去获取别名,直到获取到真实的beanName
//aliasA->aliasB->beanName
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
2:getSingleton方法
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
//判断是否有缓存起来的bean
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//singletonObjects保存的为实例化并赋值过的bean,可以直接使用
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//earlySingletonObjects主要是保存允许提前暴露出来的bean
//主要是为了解决循环依赖的问题
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
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);
}
3:getObjectForBeanInstance方法
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
//如果name是以&开头的 但是不是FactoryBean,则直接抛出异常
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// 则beanInstance可能是一个普通的bean,也可能是一个FactoryBean
// 如果是一个普通的bean,则直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
//FactoryBean创建出bean实例返回
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean> factory = (FactoryBean>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
以上对getBean主流程以及其主要的几个方法做了分析,下面将对其getBean的主流程做一个分析:
通过流程图,将其主要的流程的轮廓给描述的出来。更加的直观。在下文中,我将对Spring中createBean做一个详细的描述