春5.xのソース・旅行二十から八詳細13 populateBean A getBean

populateBeanセグメント1

プロパティを充填する前に、ほかのInstantiationAwareBeanPostProcessorプロセッサ、およびそれらにそれらを修正する機会を与えるbeanのインスタンスを、ここでは、拡張ポイントです。処理した場合postProcessAfterInstantiationメソッドが発行されfalse、それはあなたが記入するかどうかを制御できることを示し、ループとリターンの外に、プロパティを埋める停止しますが、springプロセッサの内部処理はに対処するか、カスタムプロセッサの拡張に行く必要はありません。

boolean continueWithPropertyPopulation = true;//是否让InstantiationAwareBeanPostProcessor继续执行
		// 在填充前还可以用InstantiationAwareBeanPostProcessors来修改bean
		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;
					}
				}
			}
		}
		if (!continueWithPropertyPopulation) {//如果停止处理就返回
			return;
		}

populateBeanセグメント2

デフォルトでは、自動組立モードを取得しますNOが提供されている場合、それは設定に従って組み立てられるだろう。

//获取属性值
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
		//获取自动装配模式,默认是no
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

populateBeanセグメント3

ここになりますInstantiationAwareBeanPostProcessorのプロセッサpostProcessProperties処理、

//是否有InstantiationAwareBeanPostProcessors
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {//创建PropertyValues
				pvs = mbd.getPropertyValues();
			}
			for (BeanPostProcessor bp : getBeanPostProcessors()) {//继续后置处理器处理
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		

postProcessProperties ImportAwareBeanPostProcessorのConfigurationClassPostProcessor内部クラス

これが設定されている場合、クラスの正面でConfiguration注釈が動的プロキシとなり、実装するEnhancedConfigurationインターフェースを二つあるsetBeanFactoryインターフェース方法は、それを通過しますbeanFactory

@Override
		public PropertyValues postProcessProperties(@Nullable PropertyValues pvs, Object bean, String beanName) {
			// Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's
			// postProcessProperties method attempts to autowire other configuration beans.
			if (bean instanceof EnhancedConfiguration) {
				((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
			}
			return pvs;
		}

CommonAnnotationBeanPostProcessor的postProcessProperties

ここでは、フロントに対処しますapplyMergedBeanDefinitionPostProcessorsメタデータアノテーションを注入ハンドル。

	@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
		}
		return pvs;
	}

InjectionMetadata的注入

フロントレジスタを横断InjectedElementした後、注入されました。

	public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
		Collection<InjectedElement> checkedElements = this.checkedElements;
		Collection<InjectedElement> elementsToIterate =
				(checkedElements != null ? checkedElements : this.injectedElements);
		if (!elementsToIterate.isEmpty()) {
			for (InjectedElement element : elementsToIterate) {
				if (logger.isTraceEnabled()) {
					logger.trace("Processing injected element of bean '" + beanName + "': " + element);
				}
				element.inject(target, beanName, pvs);
			}
		}
	}

InjectedElement的注入

プロパティまたはメソッドを注入するが、最初の注入方法は、値が設定されているかどうかを決定するために、直接返し、集合注射を持っていません。

		protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
				throws Throwable {

			if (this.isField) {//属性注入
				Field field = (Field) this.member;
				ReflectionUtils.makeAccessible(field);
				field.set(target, getResourceToInject(target, requestingBeanName));
			}
			else {
				if (checkPropertySkipping(pvs)) {
					return;
				}
				try {//方法注入
					Method method = (Method) this.member;
					ReflectionUtils.makeAccessible(method);
					method.invoke(target, getResourceToInject(target, requestingBeanName));
				}
				catch (InvocationTargetException ex) {
					throw ex.getTargetException();
				}
			}
		}

checkPropertySkipping

与えられた値を定義するための時間であれば、注入をスキップするかどうかを決定するプロパティは無視されます。

protected boolean checkPropertySkipping(@Nullable PropertyValues pvs) {
			Boolean skip = this.skip;
			if (skip != null) {
				return skip;
			}
			if (pvs == null) {
				this.skip = false;
				return false;
			}
			synchronized (pvs) {
				skip = this.skip;
				if (skip != null) {
					return skip;
				}
				if (this.pd != null) {
					if (pvs.contains(this.pd.getName())) {
						// 给定了值了就忽略,直接返回
						this.skip = true;
						return true;
					}
					else if (pvs instanceof MutablePropertyValues) {//如果是可变的话,就注册到处理过的属性集合里
						((MutablePropertyValues) pvs).registerProcessedProperty(this.pd.getName());
					}
				}
				this.skip = false;
				return false;
			}
		}

ResourceElement的getResourceToInject

getResourceToInject方法が鍵となり、実際には、されたInjectedElement抽象メソッドは、サブクラスのような異なる実装クラス、持っているResourceElementEjbRefElementWebServiceRefElement我々はに焦点を当てるもちろんのResourceElement事を、彼らは見ることができ、他の利害関係を持っています。

この方法は、最初に何のメタデータの注釈が存在しないかを決定Lazy、遅延ロードは、ノートがあれば、プロキシクラスを作成し、内部がAOP行うには、プロキシの工場は、バックの詳細は述べ、その後、そこにあるgetTargetコールを取得するには時間が必要な場合があり、プロキシ方法。直接でない場合getResource

@Override
		protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
			return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
					getResource(this, requestingBeanName));
		}

CommonAnnotationBeanPostProcessor的のgetResource

まず決定しjndi、その後、注入を呼び出しautowireResource、我々は一般的ですautowireResource

protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
			throws NoSuchBeanDefinitionException {

		if (StringUtils.hasLength(element.mappedName)) {
			return this.jndiFactory.getBean(element.mappedName, element.lookupType);
		}
		if (this.alwaysUseJndiLookup) {
			return this.jndiFactory.getBean(element.name, element.lookupType);
		}
		if (this.resourceFactory == null) {
			throw new NoSuchBeanDefinitionException(element.lookupType,
					"No resource factory configured - specify the 'resourceFactory' property");
		}
		return autowireResource(this.resourceFactory, element, requestingBeanName);
	}

autowireResourceもっと重要な、我々は、後でそれを再訪しました。

さて、今日ここに、私たちは自分自身の学習、限られた容量を理解し、偉大な神は見スプレーしないで、言い訳してください、助けの調査に希望と理解しています。

公開された235元の記事 ウォン称賛74 ビュー30000 +

おすすめ

転載: blog.csdn.net/wangwei19871103/article/details/105139638