在 Spring源码系列:BeanFactory的创建 文章中我们谈到了BeanFactory这容器,这个里面提供了注入的实现接口。其具体的实现还需要从AbstractBeanFactory和DefaultListableBeanFactory中来看。今天就先撸一下AbstractBeanFactory这个类中的getBean这个方法。
getBean提供了四个重载方法,如下:
//通过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的地方,也是触发依赖注入发生的地方。(这个方法比较长,分段来说)
先来看下方法的定义:
@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里面):
else { //分解到下面 }
//在当前线程中,返回指定的prototype bean是否正在创建。 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }
下面这段的作用是对Ioc容器中的BeanDefinition是否存在进行检测,先是检测当前BeanFactory中是否能够获取到,如果取不到则继续到双亲容器中进行尝试获取,如果双亲还是取不到,则继续向上一级父容器中尝试获取。
// 检查该工厂是否存在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。
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的初始化。