天天看點

SpringIoC依賴注入的過程(三) SpringIoC依賴注入的過程(三)

SpringIoC依賴注入的過程(三)

    上文說到doCreateBean的applyMergedBeanDefinitionPostProcessors方法找到了所有的聲明了Autowired标注和Resource标注的字段和方法,以及聲明了PostConstruct和PreDestroy标注的方法。到此為止,bean的依賴關系都已經解析到BeanDefinition中,接下來就是利用這些依賴關系進行注入。繼續看doCreateBean方法的剩餘部分

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, new ObjectFactory() {
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}
           

    這部分代碼是什麼意思呢?可以看到有一個變量名字叫做allowCircularReferences,可以猜出這裡就是處理循環引用的。比如Service1引用了Service2,而Service2也引用了Service1。如果現在正在建立Service1,發現它依賴了Service2,在向Service1注入Service2的過程中肯定要先去建立Service2。這時候發現又要建立Service1,當然不能再建立一個Service1了,而是先将未初始化好的Service1引用先注入到Service2中。然後初始化Service2後再回過來注入到Service1中。關于循環引用的依賴注入過程也許後續會專門的詳細解讀,今天簡單帶過,先把主體的流程說通。下面說SpringIoC的重頭戲, populateBean方法,依賴注入就發生在這裡。還是分段說吧,免得代碼太長

boolean continueWithPropertyPopulation = true;

		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}
           

    上面是要講的populateBean方法中的第一段代碼,它調用所有的InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation的方法。 InstantiationAwareBeanPostProcessor的實作類有下面這些                             

SpringIoC依賴注入的過程(三) SpringIoC依賴注入的過程(三)

     postProcessAfterInstantiation是在bean被執行個體化以後留出的擴充方法,但實際上并沒有用到,上面那些類都是直接傳回了true,依賴注入不是發生在這裡。我們繼續往下看

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
           

   這裡是一處依賴注入發生的地方,如果目前的bean是AUTOWIRE_BY_NAME或者AUTOWIRE_BY_TYPE的主動注入模式,則會觸發相應的注入方法。先看一下autowireByName

protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			if (containsBean(propertyName)) {
				Object bean = getBean(propertyName);
				pvs.add(propertyName, bean);
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}
           

   很好了解,先找到需要注入的依賴的bean的名字,然後遞歸調用getBean。getBean執行完後就會傳回依賴的bean的執行個體,放入到PropertyValues中。再看看autowireByType是怎麼做的

protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}

		Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			try {
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				// Don't try autowiring by type for type Object: never makes sense,
				// even if it technically is a unsatisfied, non-simple property.
				if (!Object.class.equals(pd.getPropertyType())) {
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// Do not allow eager init for type matching in case of a prioritized post-processor.
					boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
						pvs.add(propertyName, autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isDebugEnabled()) {
							logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
									propertyName + "' to bean named '" + autowiredBeanName + "'");
						}
					}
					autowiredBeanNames.clear();
				}
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}
           

   根據類型自動注入的過程稍複雜一些,總體的過程是這樣的。通過resolveDependency方法最終調用DefaultListableBeanFactory中的doResolveDependency方法,然後得到需要注入的bean的執行個體,同樣先放到 PropertyValues中。不早了,先到這裡,剩下的後面繼續。