Spring源码分析 IOC依赖注入

Spring源码分析 IOC依赖注入

基于上篇 Spring源码分析 Bean创建和获取 依赖注入是在bean创建时候完成,bean的创建触发过程如下

  • 单例模式非延迟加载的对象,会在IOC容器初始化的时候被创建且初始化
  • 非单例模式或者延迟加载的对象,应用第一次向容器索要该Bean对象的时候被创建且初始化

基于创建bean源码分析IOC依赖注入

public Object getBean(String name) throws BeansException {
    		return doGetBean(name, null, null, false);
    	}
    	protected Object doGetBean(String name, Class requiredType, final Object args[], boolean typeCheckOnly)
            throws BeansException
        {
            final String beanName;
            Object bean;
            final RootBeanDefinition mbd;
            Object prototypeInstance;
            beanName = transformedBeanName(name);
             // 先尝试从缓存中获取bean,对于那些单例模式的Bean,缓存获取
            Object sharedInstance = getSingleton(beanName);
            if(sharedInstance != null && args == null)
            {
                if(logger.isDebugEnabled())
                    if(isSingletonCurrentlyInCreation(beanName))
                        logger.debug((new StringBuilder()).append("Returning eagerly cached instance of singleton bean '").append(beanName).append("' that is not fully initialized yet - a consequence of a circular reference").toString());
                    else
                        logger.debug((new StringBuilder()).append("Returning cached instance of singleton bean '").append(beanName).append("'").toString());
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
                break MISSING_BLOCK_LABEL_544;
            }
            if(isPrototypeCurrentlyInCreation(beanName))
                throw new BeanCurrentlyInCreationException(beanName);
            //IOC-1
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if(parentBeanFactory != null && !containsBeanDefinition(beanName))
            {
                String nameToLookup = originalBeanName(name);
                if(args != null)
                    return parentBeanFactory.getBean(nameToLookup, args);
                else
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            if(!typeCheckOnly)
                markBeanAsCreated(beanName);
            mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);
            //获取当前Bean依赖的Bean,可能会触发getBean方法的递归调用
            String dependsOn[] = mbd.getDependsOn();
            if(dependsOn != null)
            {
                String arr$[] = dependsOn;
                int len$ = arr$.length;
                for(int i$ = 0; i$ < len$; i$++)
                {
                    String dependsOnBean = arr$[i$];
                    getBean(dependsOnBean);
                    registerDependentBean(dependsOnBean, beanName);
                }
    
            }
            if(mbd.isSingleton())
            {
                sharedInstance = getSingleton(beanName, new ObjectFactory() {
    
                    public Object getObject()
                        throws BeansException
                    {
                        try
                        {
                            return createBean(beanName, mbd, args);
                        }
                        catch(BeansException ex)
                        {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }
    
                    final String val$beanName;
                    final RootBeanDefinition val$mbd;
                    final Object val$args[];
                    final AbstractBeanFactory this$0;
    
                
                {
                    this$0 = AbstractBeanFactory.this;
                    beanName = s;
                    mbd = rootbeandefinition;
                    args = aobj;
                    super();
                }
                }
    );
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                break MISSING_BLOCK_LABEL_544;
            }
            if(!mbd.isPrototype())
                break MISSING_BLOCK_LABEL_399;
            prototypeInstance = null;
            beforePrototypeCreation(beanName);
            prototypeInstance = createBean(beanName, mbd, args);
            afterPrototypeCreation(beanName);
            break MISSING_BLOCK_LABEL_383;
            Exception exception;
            exception;
            afterPrototypeCreation(beanName);
            throw exception;
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            break MISSING_BLOCK_LABEL_544;
            String scopeName = mbd.getScope();
            Scope scope = (Scope)scopes.get(scopeName);
            if(scope == null)
                throw new IllegalStateException((new StringBuilder()).append("No Scope registered for scope '").append(scopeName).append("'").toString());
            try
            {
                Object scopedInstance = scope.get(beanName, new ObjectFactory() {
    
                    public Object getObject()
                        throws BeansException
                    {
                        beforePrototypeCreation(beanName);
                        Object obj = createBean(beanName, mbd, args);
                        afterPrototypeCreation(beanName);
                        return obj;
                        Exception exception1;
                        exception1;
                        afterPrototypeCreation(beanName);
                        throw exception1;
                    }
    
                    final String val$beanName;
                    final RootBeanDefinition val$mbd;
                    final Object val$args[];
                    final AbstractBeanFactory this$0;
    
                
                {
                    this$0 = AbstractBeanFactory.this;
                    beanName = s;
                    mbd = rootbeandefinition;
                    args = aobj;
                    super();
                }
                }
    );
                bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            }
            catch(IllegalStateException ex)
            {
                throw new BeanCreationException(beanName, (new StringBuilder()).append("Scope '").append(scopeName).append("' is not active for the current thread; ").append("consider defining a scoped proxy for this bean if you intend to refer to it from a singleton").toString(), ex);
            }
            if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass()))
            {
                try
                {
                    return getTypeConverter().convertIfNecessary(bean, requiredType);
                }
                catch(TypeMismatchException ex)
                {
                    if(logger.isDebugEnabled())
                        logger.debug((new StringBuilder()).append("Failed to convert bean '").append(name).append("' to required type [").append(ClassUtils.getQualifiedName(requiredType)).append("]").toString(), ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            } else
            {
                return bean;
            }
        }

如图所示 IOC-1进行 对IOC容器中BeanDefinition是否存在进行检查
接下来分析bean创建,类AbstractAutowireCapableBeanFactory中createBean()调用doCreateBean(),源码如下

protected Object doCreateBean(final String beanName,
			final RootBeanDefinition mbd, Object args[]) {
		BeanWrapper instanceWrapper = null;
		//如果是单例模式,现将缓存中的同名Bean删除
		if (mbd.isSingleton())
			instanceWrapper = (BeanWrapper) factoryBeanInstanceCache
					.remove(beanName);
		if (instanceWrapper == null)
		//创建Bean
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		final Object bean = instanceWrapper == null ? null : instanceWrapper
				.getWrappedInstance();
		Class beanType = instanceWrapper == null ? null : instanceWrapper
				.getWrappedClass();
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				mbd.postProcessed = true;
			}
		}
		boolean earlySingletonExposure = mbd.isSingleton()
				&& allowCircularReferences
				&& isSingletonCurrentlyInCreation(beanName);
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled())
				logger.debug((new StringBuilder())
						.append("Eagerly caching bean '")
						.append(beanName)
						.append("' to allow for resolving potential circular references")
						.toString());
			addSingletonFactory(beanName, new ObjectFactory() {

				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}

				final String val$beanName;
				final RootBeanDefinition val$mbd;
				final Object val$bean;
				final AbstractAutowireCapableBeanFactory this$0;

				{
					this$0 = AbstractAutowireCapableBeanFactory.this;
					beanName = s;
					mbd = rootbeandefinition;
					bean = obj;
					super();
				}
			});
		}
		Object exposedObject = bean;
		try {
		//注入1
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null)
				exposedObject = initializeBean(beanName, exposedObject, mbd);
		} catch (Throwable ex) {
			if ((ex instanceof BeanCreationException)
					&& beanName.equals(((BeanCreationException) ex)
							.getBeanName()))
				throw (BeanCreationException) ex;
			else
				throw new BeanCreationException(mbd.getResourceDescription(),
						beanName, "Initialization of bean failed", ex);
		}
		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null)
				if (exposedObject == bean)
					exposedObject = earlySingletonReference;
				else if (!allowRawInjectionDespiteWrapping
						&& hasDependentBean(beanName)) {
					String dependentBeans[] = getDependentBeans(beanName);
					Set actualDependentBeans = new LinkedHashSet(
							dependentBeans.length);
					String arr$[] = dependentBeans;
					int len$ = arr$.length;
					for (int i$ = 0; i$ < len$; i$++) {
						String dependentBean = arr$[i$];
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean))
							actualDependentBeans.add(dependentBean);
					}

					if (!actualDependentBeans.isEmpty())
						throw new BeanCurrentlyInCreationException(
								beanName,
								(new StringBuilder())
										.append("Bean with name '")
										.append(beanName)
										.append("' has been injected into other beans [")
										.append(StringUtils
												.collectionToCommaDelimitedString(actualDependentBeans))
										.append("] in its raw version as part of a circular reference, but has eventually been ")
										.append("wrapped. This means that said other beans do not use the final version of the ")
										.append("bean. This is often the result of over-eager type matching - consider using ")
										.append("'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.")
										.toString());
				}
		}
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		} catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(),
					beanName, "Invalid destruction signature", ex);
		}
		return exposedObject;
	}

如图 //注入1 进行依赖注入 ,进入populateBean()查看注入代码

protected void populateBean(String beanName, RootBeanDefinition mbd,
			BeanWrapper bw) {
		PropertyValues pvs;
		boolean continueWithPropertyPopulation;
		label0: {
			pvs = mbd.getPropertyValues();
			if (bw == null)
				if (!pvs.isEmpty())
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName,
							"Cannot apply property values to null instance");
				else
					return;
			continueWithPropertyPopulation = true;
			if (mbd.isSynthetic() || !hasInstantiationAwareBeanPostProcessors())
				break label0;
			Iterator i$ = getBeanPostProcessors().iterator();
			InstantiationAwareBeanPostProcessor ibp;
			do {
				BeanPostProcessor bp;
				do {
					if (!i$.hasNext())
						break label0;
					bp = (BeanPostProcessor) i$.next();
				} while (!(bp instanceof InstantiationAwareBeanPostProcessor));
				ibp = (InstantiationAwareBeanPostProcessor) bp;
			} while (ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),
					beanName));
			continueWithPropertyPopulation = false;
		}
		label1: {
			boolean needsDepCheck;
			PropertyDescriptor filteredPds[];
			label2: {
				if (!continueWithPropertyPopulation)
					return;
					//注入2
				if (mbd.getResolvedAutowireMode() == 1
						|| mbd.getResolvedAutowireMode() == 2) {
					MutablePropertyValues newPvs = new MutablePropertyValues(
							pvs);
					if (mbd.getResolvedAutowireMode() == 1)
						autowireByName(beanName, mbd, bw, newPvs);
					if (mbd.getResolvedAutowireMode() == 2)
						autowireByType(beanName, mbd, bw, newPvs);
					pvs = newPvs;
				}
				boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
				needsDepCheck = mbd.getDependencyCheck() != 0;
				if (!hasInstAwareBpps && !needsDepCheck)
					break label1;
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw,
						mbd.allowCaching);
				if (!hasInstAwareBpps)
					break label2;
				Iterator i$ = getBeanPostProcessors().iterator();
				do {
					BeanPostProcessor bp;
					do {
						if (!i$.hasNext())
							break label2;
						bp = (BeanPostProcessor) i$.next();
					} while (!(bp instanceof InstantiationAwareBeanPostProcessor));
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					pvs = ibp.postProcessPropertyValues(pvs, filteredPds,
							bw.getWrappedInstance(), beanName);
				} while (pvs != null);
				return;
			}
			if (needsDepCheck)
				checkDependencies(beanName, mbd, filteredPds, pvs);
		}
		//注入-3
		applyPropertyValues(beanName, mbd, bw, pvs);
	}

如图所以 注入-2 ,开始进行依赖注入过程,先处理AutoWrite的注入
注入-3,对属性进行注入
后续解析bean时,最关注的还是依赖的Bean是如何解析的?

private Object resolveReference(Object argName, RuntimeBeanReference ref) {
      try {
          String refName = ref.getBeanName();
          refName = String.valueOf(evaluate(refName));
           //如果引用的Bean在双亲容器中,就从双亲容器中查找
          if (ref.isToParent()) {
              if (this.beanFactory.getParentBeanFactory() == null) {
                  throw new BeanCreationException(
                          this.beanDefinition.getResourceDescription(), this.beanName,
                          "Can't resolve reference to bean '" + refName +
                         "' in parent factory: no parent factory available");
             }
             return this.beanFactory.getParentBeanFactory().getBean(refName);
         }
           //如果在当前容器中获取Bean,会触发一个getBean的过程
         else {
             Object bean = this.beanFactory.getBean(refName);
             this.beanFactory.registerDependentBean(refName, this.beanName);
             return bean;
         }
     }
     catch (BeansException ex) {
         throw new BeanCreationException(
                 this.beanDefinition.getResourceDescription(), this.beanName,
                 "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
     }
}

依赖注入所需数据已经准备完毕,接下来将这些属性设置对应的Bean
接着分析

public void setPropertyValue(PropertyValue pv) throws BeansException {
          PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
          if (tokens == null) {
              String propertyName = pv.getName();
              BeanWrapperImpl nestedBw;
              try {
                  nestedBw = getBeanWrapperForPropertyPath(propertyName);
              }
              catch (NotReadablePropertyException ex) {
                 throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
                         "Nested property in path '" + propertyName + "' does not exist", ex);
             }
             tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
             if (nestedBw == this) {
                 pv.getOriginalPropertyValue().resolvedTokens = tokens;
             }
             //set属性
             nestedBw.setPropertyValue(tokens, pv);
         }
         else {
             setPropertyValue(tokens, pv);
         }
     }

属性设置如图标,到此 bean数据相关已经注入完毕,可使用IOC容器中存在的Bean对象

作者简介:张程 技术研究

更多文章请关注微信公众号:zachary分解狮 (frankly0423)
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值