春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
抽象メソッドは、サブクラスのような異なる実装クラス、持っているResourceElement
、EjbRefElement
とWebServiceRefElement
我々はに焦点を当てるもちろんの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
もっと重要な、我々は、後でそれを再訪しました。
さて、今日ここに、私たちは自分自身の学習、限られた容量を理解し、偉大な神は見スプレーしないで、言い訳してください、助けの調査に希望と理解しています。