在Spring源码系列:BeanFactory的建立文章中咱们谈到了BeanFactory这容器,这个里面提供了注入的实现接口。其具体的实现还须要从AbstractBeanFactory和DefaultListableBeanFactory中来看。今天就先撸一下AbstractBeanFactory这个类中的getBean这个方法。java
一、getBean方法缓存
getBean提供了四个重载方法,以下:bash
//经过name获取Bean
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
//经过name和类型获取Bean
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
//经过name和对象参数获取Bean
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
//经过name、类型和参数获取Bean
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
return doGetBean(name, requiredType, args, false);
}
复制代码
从这四个重载方法的方法体中能够看出,他们都是经过doGetBean来实现的。因此doGetBean其实才是真正获取Bean的地方,也是触发依赖注入发生的地方。(这个方法比较长,分段来讲)ide
二、doGetBean函数
先来看下方法的定义:post
@SuppressWarnings("unchecked")
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
复制代码
//返回bean名称,剥离工厂引用前缀,并将别名解析为规范名称。
final String beanName = transformedBeanName(name);
//声明当前须要返回的bean对象
Object bean;
// 先从缓存中获取bean,处理已经被建立的单例模式的bean,
//对于此类bean的请求不须要重复的建立(singleton)
Object sharedInstance = getSingleton(beanName);
复制代码
若是当前获取到的sharedInstance不为null而且参数为空,则进行FactoryBean的相关处理,并获取FactoryBean的处理结果。优化
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
//返回指定的singleton bean是否正在建立(在整个工厂内)。
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '"
+ beanName +"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//完成FactoryBean的相关处理,并用来获取FactoryBean的处理结果
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
复制代码
若是当前获取到的sharedInstance为null,咱们再来看下作了哪些处理(下面的都在一个大的else里面):ui
else {
//分解到下面
}
复制代码
//在当前线程中,返回指定的prototype bean是否正在建立。
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
复制代码
下面这段的做用是对Ioc容器中的BeanDefinition是否存在进行检测,先是检测当前BeanFactory中是否可以获取到,若是取不到则继续到双亲容器中进行尝试获取,若是双亲仍是取不到,则继续向上一级父容器中尝试获取。spa
// 检查该工厂是否存在bean定义。
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 若是没有,则继续检查父类
String nameToLookup = originalBeanName(name);
if (args != null) {
// 用明确的参数表明父项。
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// 若是没有args - >委托给标准的getBean方法。
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
复制代码
将指定的bean标记为已经建立(或即将建立);这里容许bean工厂优化其缓存以重复建立指定的bean。prototype
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
复制代码
先根据beanName来获取BeanDefinition,而后获取当前bean的全部依赖bean,这里是经过递归调用getBean来完成,直到没有任何依赖的bean为止。
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查给定的合并bean定义,可能抛出验证异常。
checkMergedBeanDefinition(mbd, beanName, args);
// 保证当前bean依赖的bean的初始化。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
//递归处理依赖bean
getBean(dep);
}
}
复制代码
下面这段就是建立一个bean实例;这里经过调用getSingleton方法来建立一个单例bean实例;从代码中能够看到,getSingleton的调用是经过getObject这个回调函数来间接调用createBean完成的。
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
//回调函数getObject
@Override
public Object getObject() throws BeansException {
try {
//建立bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//发生异常则销毁
destroySingleton(beanName);
throw ex;
}
}
});
//获取给定bean实例的对象,不管是bean实例自己,仍是FactoryBean建立的对象。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
复制代码
下面是建立prototype bean
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
//建立prototype bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
复制代码
最后是对建立的bean进行类型检查,没有问题就返回已经建立好的bean;此时这个bean是包含依赖关系的bean
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
//返回bean
return (T) bean;
复制代码
getBean是依赖注入的起点,从上面的分析能够看出,bean的建立都是经过createBean来完成具体的建立的。createBean的具体实现是在AbstractAutowireCapableBeanFactory中的,这里createBean不单单负责建立bean,还须要完成对bean的初始化。