/**
* Helper class for use in bean factory implementations,
* resolving values contained in bean definition objects
* into the actual values applied to the target bean instance.
* <p>在bean工厂实现中使用Helper类,它将beanDefinition对象中包含的值解析为应用于
* 目标bean实例的实际值</p>
*
* <p>Operates on an {@link AbstractBeanFactory} and a plain
* {@link org.springframework.beans.factory.config.BeanDefinition} object.
* Used by {@link AbstractAutowireCapableBeanFactory}.
* <p>在AbstractBeanFactory和纯BeanDefinition对象上操作。由AbstractAutowireCapableBeanFactory
* 使用</p>
*
* <p>参考博客:https://blog.csdn.net/zhuqiuhui/article/details/82391851</p>
*
* @author Juergen Hoeller
* @since 1.2
* @see AbstractAutowireCapableBeanFactory
*/
class BeanDefinitionValueResolver {
/**
* 当前Bean工厂
*/
private final AbstractAutowireCapableBeanFactory beanFactory;
/**
* 要使用的bean名
*/
private final String beanName;
/**
* beanName对应的beanDefinition
*/
private final BeanDefinition beanDefinition;
/**
* 用于解析TypeStringValues的TypeConverter
*/
private final TypeConverter typeConverter;
/**
* Create a BeanDefinitionValueResolver for the given BeanFactory and BeanDefinition.
* <p>为给定BeanFactory和BeanDefinition创建一个BeanDefinitionValueResolver实例</p>
* @param beanFactory the BeanFactory to resolve against -- 要解决的Bean工厂,即当前bean工厂
* @param beanName the name of the bean that we work on -- 我们要使用的bean名
* @param beanDefinition the BeanDefinition of the bean that we work on -- 我们要使用的bean的BeanDefinition
* @param typeConverter the TypeConverter to use for resolving TypedStringValues
* -- 用于解析TypeStringValues的TypeConverter
*/
public BeanDefinitionValueResolver(AbstractAutowireCapableBeanFactory beanFactory, String beanName,
BeanDefinition beanDefinition, TypeConverter typeConverter) {
this.beanFactory = beanFactory;
this.beanName = beanName;
this.beanDefinition = beanDefinition;
this.typeConverter = typeConverter;
}
/**
* <p>解析出value所封装的对象:
* <ol>
* <li>【如果values是RuntimeBeanReference实例】:
* <ol>
* <li>将value强转成RuntimeBeanReference对象【变量 ref】</li>
* <li>解析出对应ref所封装的Bean元信息(即Bean名,Bean类型)的Bean对象 【{@link #resolveReference(Object, RuntimeBeanReference)}】</li>
* </ol>
* </li>
* <li>【如果values是RuntimeBeanReference实例】:
* <ol>
* <li>从value中获取引用的Bean名【变量 refName】</li>
* <li>对refName进行解析,然后重新赋值给refName</li>
* <li>如果该bean工厂不包含具有refName的beanDefinintion或外部注册的singleton实例,抛出BeanDefintion存储异常</li>
* <li>返回经过解析且经过检查其是否存在于Bean工厂的引用Bean名【refName】</li>
* </ol>
* </li>
* <li>【如果value是BeanDefinitionHolder实例】:
* <ol>
* <li>将value强转为BeanDefinitionHolder对象【变量 bdHolder】</li>
* <li>根据bdHolder所封装的Bean名和BeanDefinition对象解析出内部Bean对象并返回出去 【{@link #resolveInnerBean(Object, String, BeanDefinition)}】</li>
* </ol>
* </li>
* <li>【如果value是BeanDefinition实例】:
* <ol>
* <li>将value强转为BeanDefinition对象【变量 bd】</li>
* <li>拼装内部Bean名:"(inner bean)#"+bd的身份哈希码的十六进制字符串形式【变量 innerBeanName】</li>
* <li>根据innerBeanName和bd解析出内部Bean对象并返回出去 【{@link #resolveInnerBean(Object, String, BeanDefinition)}】</li>
* </ol>
* </li>
* <li>【如果values是DependencyDesciprtor实例】:
* <ol>
* <li>定义一个用于存放所找到的所有候选Bean名的集合,初始化长度为4【变量 autowiredBeanNames】</li>
* <li>根据descriptor的依赖类型解析出与descriptor所包装的对象匹配的候选Bean对象【变量 result】</li>
* <li>遍历autowiredBeanNames,元素为autowiredBeanName:
* <ol>
* <li>如果该bean工厂包含具有autowiredBeanName的beanDefinition或外部注册的singleton实例,
* 注册autowiredBeanName与beanName的依赖关系</li>
* <li>返回与descriptor所包装的对象匹配的候选Bean对象【result】</li>
* </ol>
* </li>
* </ol>
* </li>
* <li>【如果value是ManagedArray实例】:
* <ol>
* <li>将value强转为ManagedArray对象【变量 array】</li>
* <li>获取array的已解析元素类型【变量 elementType】</li>
* <li>如果elementType为null:
* <ol>
* <li>获取arry的元素类型名,指array标签的value-type属性【变量 elemetTypeName】</li>
* <li>如果elementTypeName不是空字符串:
* <ol>
* <li>让elemetType引用 使用Bean工厂的Bean类型加载器加载elementTypeName对应的Class对象</li>
* <li>让array#resolvedElementType属性引用elementType</li>
* <li>捕捉加载elementTypeName对应的Class对象的所有异常,抛出Bean创建异常并引用ex:错误解析数组类型</li>
* </ol>
* </li>
* <li>让elementType默认使用Object类对象</li>
* </ol>
* </li>
* <li>解析ManagedArray对象,以得到解析后的数组对象 【{@link #resolveManagedArray(Object, List, Class)}】</li>
* </ol>
* </li>
* <li>【如果value是ManagedArray实例】:
* <ol>
* <li>解析ManagedList对象,以得到解析后的List对象并结果返回出去 【{@link #resolveManagedList(Object, List)}】</li>
* </ol>
* </li>
* <li>【如果value是ManagedSet对象】:
* <ol>
* <li>解析ManagedSet对象,以得到解析后的Set对象并结果返回出去</li>
* </ol>
* </li>
* <li>【如果value是ManagedMap对象】:
* <ol>
* <li> 解析ManagedMap对象,以得到解析后的Map对象并结果返回出去 【{@link #resolveManagedMap(Object, Map)}】</li>
* </ol>
* </li>
* <li>【如果value是ManagedProperties对象】:
* <ol>
* <li>将value强转为Properties对象【变量 original】</li>
* <li>定义一个用于存储将original的所有Property的键/值解析后的键/值的Properties对象【变量 copy】</li>
* <li>遍历original,键名为propKey,值为propValue:
* <ol>
* <li>如果proKey是TypeStringValue实例,在propKey封装的value可解析成表达式的情况下,将propKey封装的value评估为
* 表达式并解析出表达式的值</li>
* <li>如果proValue式TypeStringValue实例,在propValue封装的value可解析成表达式的情况下,将propValue封装的value评估为表达式
* 并解析出表达式的值</li>
* <li>如果proKey或者propValue为null,抛出Bean创建异常</li>
* <li>将propKey和propValue添加到copy中</li>
* </ol>
* </li>
* <li>返回copy</li>
* </ol>
* </li>
* <li>【如果value时TypeStringValue实例】:
* <ol>
* <li>将value强转为TypedStringValue对象 【变量 typedStringValue】</li>
* <li>在typedStringValue封装的value可解析成表达式的情况下,将typedStringValue封装的
* value评估为表达式并解析出表达式的值【变量 valueObject】</li>
* <li>在typedStringValue中解析目标类型【变量 resolvedTargetType】</li>
* <li>如果resolvedTargetType不为null,使用typeConverter将值转换为所需的类型并返回出去</li>
* <li>否则,返回并解析出来表达式的值【valueObject】</li>
* <li>捕捉在解析目标类型或转换类型过程中抛出的异常,抛出Bean创建异常</li>
* </ol>
* </li>
* <li>【如果value是NullBean实例】:直接返回null</li>
* <li>【如果value是其他类型】:对于value是String/String[]类型会尝试评估为表达式并解析出表达式的值,
* 其他类型直接返回value.</li>
* </ol>
* </p>
* Given a PropertyValue, return a value, resolving any references to other
* beans in the factory if necessary. The value could be:
* <p>给定一个PropertyValue,返回一个值,如有必要,解析对工厂中其他bean的任何引用,
* 该值可以是:</p>
* <li>A BeanDefinition, which leads to the creation of a corresponding
* new bean instance. Singleton flags and names of such "inner beans"
* are always ignored: Inner beans are anonymous prototypes.
* <li>BeanDefinition,它导致创建相应的新bean实例。此类"内部bean"的单例标志
* 和名称始终被忽略:内部bean是匿名原型</li>
* <li>A RuntimeBeanReference, which must be resolved.
* <li>一个RuntimeBeanReference,必需解决</li>
* <li>A ManagedList. This is a special collection that may contain
* RuntimeBeanReferences or Collections that will need to be resolved.
* <li>一个ManagedList.这是一个特殊的集合,其中可能包含需要解决的RuntimeBeanReferences或
* Collections</li>
* <li>A ManagedSet. May also contain RuntimeBeanReferences or
* Collections that will need to be resolved.
* <p>一个ManagedSet.也可能包含需要解决的RuntimeBeanReference或Collections</p>
* <li>A ManagedMap. In this case the value may be a RuntimeBeanReference
* or Collection that will need to be resolved.
* <p>一个ManagedMap.在这种情况下,该值可能是需要解析的RuntimeBeanReference或
* Collection。</p>
* <li>An ordinary object or {@code null}, in which case it's left alone.
* <p>普通对象或null,在这种情况下,将其保留</p>
* @param argName the name of the argument that the value is defined for
* -- 为其定义值得参数名称
* @param value the value object to resolve -- 要解决的对象值
* @return the resolved object -- 解析的对象
*/
@Nullable
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
// We must check each value to see whether it requires a runtime reference
// to another bean to be resolved.
// 我们必需检查每个值,以查看它是否需要对另一个bean的运行时引用才能解决
// RuntimeBeanReference:当属性值对象是工厂中另一个bean的引用时,使用不可变的占位符类,在运行时进行解析
// 在下面这种配置就会生成RuntimeBeanReference:
// <bean class="foo.bar.xxx">
// <property name="referBeanName" ref="otherBeanName" />
// </bean>
// 如果values是RuntimeBeanReference实例
if (value instanceof RuntimeBeanReference) {
//将value强转成RuntimeBeanReference对象
RuntimeBeanReference ref = (RuntimeBeanReference) value;
//解析出对应ref所封装的Bean元信息(即Bean名,Bean类型)的Bean对象:
return resolveReference(argName, ref);
}
//RuntimeBeanNameReference对应于<idref bean="bea" />.
// idref注入的是目标bean的id而不是目标bean的实例,同时使用idref容器在部署的时候还会验证这个名称的bean
// 是否真实存在。其实idref就跟value一样,只是将某个字符串注入到属性或者构造函数中,只不过注入的是某个
// Bean定义的id属性值:
// 即: <idref bean="bea" /> 等同于 <value>bea</value>
// 参考博客:https://www.cnblogs.com/softidea/p/5815785.html https://www.cnblogs.com/Mrfanl/p/9757780.html
// 如果values是RuntimeBeanReference实例
else if (value instanceof RuntimeBeanNameReference) {
//从value中获取引用的Bean名
String refName = ((RuntimeBeanNameReference) value).getBeanName();
//对refName进行解析,然后重新赋值给refName
refName = String.valueOf(doEvaluate(refName));
//如果该bean工厂不包含具有refName的beanDefinintion或外部注册的singleton实例
if (!this.beanFactory.containsBean(refName)) {
//抛出BeanDefintion存储异常:argName的Bean引用中的Bean名'refName'无效
throw new BeanDefinitionStoreException(
"Invalid bean name '" + refName + "' in bean reference for " + argName);
}
//返回经过解析且经过检查其是否存在于Bean工厂的引用Bean名【refName】
return refName;
}
//BeanDefinitionHolder:具有名称和别名的bean定义的持有者,可以注册为内部bean的占位符
// 出现BeanDefinitionHolder的情况,一般是内部Bean配置:https://www.cnblogs.com/shamo89/p/9917663.html
//如果value是BeanDefinitionHolder实例
else if (value instanceof BeanDefinitionHolder) {
// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
// 解决BeanDefinitionHolder:包含具有名称和别名的BenDefinition
//将value强转为BeanDefinitionHolder对象
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
//根据bdHolder所封装的Bean名和BeanDefinition对象解析出内部Bean对象
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
//一般在内部匿名bean的配置才会出现BeanDefinition,如下:
//<bean id="myStudent" class="com.hk.spring.di10.Student" autowire="byType">
// <property name="name" value="张三"/>
// <property name="age" value="9"/>
// <property name="school">
// <!-- 内部匿名bean -->
// <bean class="com.hk.spring.di10.School">
// <property name="schloolName" value="红林小学"/>
// </bean>
// </property>
//</bean>
//如果value是BeanDefinition实例
else if (value instanceof BeanDefinition) {
// Resolve plain BeanDefinition, without contained name: use dummy name.
// 解析纯BeanDefinition,不包含名称:使用虚拟名称
//将value强转为BeanDefinition对象
BeanDefinition bd = (BeanDefinition) value;
//拼装内部Bean名:"(inner bean)#"+bd的身份哈希码的十六进制字符串形式
String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
ObjectUtils.getIdentityHexString(bd);
//根据innerBeanName和bd解析出内部Bean对象
return resolveInnerBean(argName, innerBeanName, bd);
}
//如果values是DependencyDesciprtor实例
else if (value instanceof DependencyDescriptor) {
//定义一个用于存放所找到的所有候选Bean名的集合,初始化长度为4
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
//根据descriptor的依赖类型解析出与descriptor所包装的对象匹配的候选Bean对象
Object result = this.beanFactory.resolveDependency(
(DependencyDescriptor) value, this.beanName, autowiredBeanNames, this.typeConverter);
//遍历autowiredBeanNames
for (String autowiredBeanName : autowiredBeanNames) {
//如果该bean工厂包含具有autowiredBeanName的beanDefinition或外部注册的singleton实例:
if (this.beanFactory.containsBean(autowiredBeanName)) {
//注册autowiredBeanName与beanName的依赖关系
this.beanFactory.registerDependentBean(autowiredBeanName, this.beanName);
}
}
//返回与descriptor所包装的对象匹配的候选Bean对象【result】
return result;
}
//一般在array标签才会出现ManagedArray,如下:
//<property name="arrays">
// <array>
// <value>数据1</value>
// <value>数据2</value>
// <value>数据3</value>
// </array>
//</property>
//如果value是ManagedArray实例
else if (value instanceof ManagedArray) {
// May need to resolve contained runtime references.
// 可能需要解析包含的运行时引用
//将value强转为ManagedArray对象
ManagedArray array = (ManagedArray) value;
//获取array的已解析元素类型
Class<?> elementType = array.resolvedElementType;
//如果elementType为null
if (elementType == null) {
//获取arry的元素类型名,指array标签的value-type属性
String elementTypeName = array.getElementTypeName();
//如果elementTypeName不是空字符串
if (StringUtils.hasText(elementTypeName)) {
try {
//使用Bean工厂的Bean类型加载器加载elementTypeName对应的Class对象。
elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
//让array#resolvedElementType属性引用elementType
array.resolvedElementType = elementType;
}
//捕捉加载elementTypeName对应的Class对象的所有异常
catch (Throwable ex) {
// Improve the message by showing the context.
// 通过显示上下问来改善消息
// 抛出Bean创建异常并引用ex:错误解析数组类型
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error resolving array type for " + argName, ex);
}
}
else {
//让elementType默认使用Object类对象
elementType = Object.class;
}
}
//解析ManagedArray对象,以得到解析后的数组对象
return resolveManagedArray(argName, (List<?>) value, elementType);
}
//一般在list标签才会出现ManagedList,如下:
// <property name="list">
// <list>
// <value>123</value>
// <value>ABC</value>
// <value>数据String</value>
// </list>
// </property>
//如果value是ManagedArray实例
else if (value instanceof ManagedList) {
// May need to resolve contained runtime references.
// 可能需要解析包含的运行时引用
//解析ManagedList对象,以得到解析后的List对象并结果返回出去
return resolveManagedList(argName, (List<?>) value);
}
//一般在set标签才会出现ManagedList,如下:
//<set>
// <ref bean="otherBean" />
// <ref bean="otherBean" />
// <bean class="com.zhengqing._03_di.OtherBean" />
// <bean class="com.zhengqing._03_di.OtherBean" />
//</set>
//如果value是ManagedSet对象
else if (value instanceof ManagedSet) {
// May need to resolve contained runtime references.
// 可能需要解析包含的运行时引用
//解析ManagedSet对象,以得到解析后的Set对象并结果返回出去
return resolveManagedSet(argName, (Set<?>) value);
}
//一般在map标签才会出现ManagedMap,如下
//<map>
// <entry key="1" value-ref="user1"></entry>
// <entry key="2" value-ref="user2"></entry>
//</map>
//如果value是ManagedMap对象
else if (value instanceof ManagedMap) {
// May need to resolve contained runtime references.
//可能需要解析包含的运行时引用
// 解析ManagedMap对象,以得到解析后的Map对象并结果返回出去
return resolveManagedMap(argName, (Map<?, ?>) value);
}
//一般props标签才会出现ManagedProperties,如下:
//<props>
// <prop key="setA*">PROPAGATION_REQUIRED</prop>
// <prop key="rollbackOnly">PROPAGATION_REQUIRED</prop>
// <prop key="echoException">PROPAGATION_REQUIRED,+javax.servlet.ServletException,-java.lang.Exception</prop>
//</props>
//如果value是ManagedProperties对象
else if (value instanceof ManagedProperties) {
//将value强转为Properties对象
Properties original = (Properties) value;
//定义一个用于存储将original的所有Property的键/值解析后的键/值的Properties对象
Properties copy = new Properties();
//遍历original,键名为propKey,值为propValue
original.forEach((propKey, propValue) -> {
//如果proKey是TypeStringValue实例
if (propKey instanceof TypedStringValue) {
//在propKey封装的value可解析成表达式的情况下,将propKey封装的value评估为表达式并解析出表达式的值
propKey = evaluate((TypedStringValue) propKey);
}
//如果proValue式TypeStringValue实例
if (propValue instanceof TypedStringValue) {
//在propValue封装的value可解析成表达式的情况下,将propValue封装的value评估为表达式并解析出表达式的值
propValue = evaluate((TypedStringValue) propValue);
}
//如果proKey或者propValue为null
if (propKey == null || propValue == null) {
//抛出Bean创建异常:转换argName的属性键/值时出错:解析为null
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error converting Properties key/value pair for " + argName + ": resolved to null");
}
//将propKey和propValue添加到copy中
copy.put(propKey, propValue);
});
//返回copy
return copy;
}
//如果value时TypeStringValue实例
else if (value instanceof TypedStringValue) {
// Convert value to target type here.
// 在此处将value转换为目标类型
//将value强转为TypedStringValue对象
TypedStringValue typedStringValue = (TypedStringValue) value;
//在typedStringValue封装的value可解析成表达式的情况下,将typedStringValue封装的
// value评估为表达式并解析出表达式的值
Object valueObject = evaluate(typedStringValue);
try {
//在typedStringValue中解析目标类型
Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
//如果resolvedTargetType不为null
if (resolvedTargetType != null) {
//使用typeConverter将值转换为所需的类型
return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
}
else {
//返回并解析出来表达式的值
return valueObject;
}
}
//捕捉在解析目标类型或转换类型过程中抛出的异常
catch (Throwable ex) {
// Improve the message by showing the context.
// 通过显示上下文来改善消息
// 抛出Bean创建异常:为argName转换键入的字符串值时错误
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error converting typed String value for " + argName, ex);
}
}
//如果value时NullBean实例
else if (value instanceof NullBean) {
//直接返回null
return null;
}
else {
//对于value是String/String[]类型会尝试评估为表达式并解析出表达式的值,其他类型直接返回value.
return evaluate(value);
}
}
/**
* <p>在value封装的value可解析成表达式的情况下,将value封装的value评估为表达式并解析出表达式的值
* <ol>
* <li>如有必要(value可解析成表达式的情况下),将value封装的value评估为表达式【变量 result】</li>
* <li>如果result与value所封装的value不相等,将value标记为动态,即包含一个表达式,
* 因此不进行缓存</li>
* <li>返回result</li>
* </ol>
* </p>
* Evaluate the given value as an expression, if necessary.
* <p>如有必要,将给定值作为表达式求值</p>
* @param value the candidate value (may be an expression) -- 候选值(可以是表达式)
* @return the resolved value -- 解析值
*/
@Nullable
protected Object evaluate(TypedStringValue value) {
//如有必要(value可解析成表达式的情况下),将value封装的value评估为表达式并解析出表达式的值
Object result = doEvaluate(value.getValue());
//如果result与value所封装的value不相等
if (!ObjectUtils.nullSafeEquals(result, value.getValue())) {
//将value标记为动态,即包含一个表达式,因此不进行缓存
value.setDynamic();
}
//返回result
return result;
}
/**
* <p>对于value是String/String[]类型会尝试评估为表达式并解析出表达式的值,其他类型直接返回value:
* <ol>
* <li>如果value是String对象,如有必要(value可解析成表达式的情况下),将value评估为表达式并
* 解析出表达式的值并返回出去 【{@link #doEvaluate(String)}】</li>
* <li>如果value是String数组对象:
* <ol>
* <li>将value强转为String数组【变量 values】</li>
* <li>定义是否经过解析的标记,默认为false,表示未经过解析【变量 actuallyResolved】</li>
* <li>定义用于存放解析的值的Object数组,长度为values的长度【变量 resolvedValues】</li>
* <li>遍历values(以fori形式):
* <ol>
* <li>获取第i个values元素【变量 originalValue】</li>
* <li>如有必要(value可解析成表达式的情况下),将originalValue评估为表达式并解析出表达式的值</li>
* <li>如果resolvedValue与orgininalValue不是同一个对象,经过解析标记为true,表示已经过解析</li>
* <li>将resolvedValue赋值第i个resolvedValues元素中</li>
* </ol>
* </li>
* <li>如果已经过解析,返回解析后的数组【resovledValues】;否则返回values</li>
* </ol>
* </li>
* <li>其他类型直接返回value</li>
* </ol>
* </p>
* Evaluate the given value as an expression, if necessary.
* <p>如有必要,将给定值作为表达式求值</p>
* @param value the original value (may be an expression) -- 原始(可以是表达式)
* @return the resolved value if necessary, or the original value
* -- 必要时解析值或原始值
*/
@Nullable
protected Object evaluate(@Nullable Object value) {
//如果value是String对象
if (value instanceof String) {
//如有必要(value可解析成表达式的情况下),将value评估为表达式并解析出表达式的值并返回出去
return doEvaluate((String) value);
}
//如果value是String数组对象
else if (value instanceof String[]) {
//将value强转为String数组
String[] values = (String[]) value;
//是否经过解析的标记,默认为false
boolean actuallyResolved = false;
//定义用于存放解析的值的Object数组,长度为values的长度
Object[] resolvedValues = new Object[values.length];
//遍历values(以fori形式)
for (int i = 0; i < values.length; i++) {
//获取第i个values元素
String originalValue = values[i];
//如有必要(value可解析成表达式的情况下),将originalValue评估为表达式并解析出表达式的值
Object resolvedValue = doEvaluate(originalValue);
//如果resolvedValue与orgininalValue不是同一个对象
if (resolvedValue != originalValue) {
//经过解析标记为true,表示已经过解析
actuallyResolved = true;
}
//将resolvedValue赋值第i个resolvedValues元素中
resolvedValues[i] = resolvedValue;
}
//如果已经过解析,返回解析后的数组【resovledValues】;否则返回values
return (actuallyResolved ? resolvedValues : values);
}
else {
//其他类型直接返回value
return value;
}
}
/**
* Evaluate the given String value as an expression, if necessary.
* <p>如有必要(value可解析成表达式的情况下),将给定的String值评估为表达式并解析出表达式的值</p>
* @param value the original value (may be an expression)
* -- 原始值(可能式一个表达式)
* @return the resolved value if necessary, or the original String value
* -- 必要时解析的值或原始String值
*/
@Nullable
private Object doEvaluate(@Nullable String value) {
//评估value,如果value是可解析表达式,会对其进行解析,否则直接返回value
return this.beanFactory.evaluateBeanDefinitionString(value, this.beanDefinition);
}
/**
* Resolve the target type in the given TypedStringValue.
* <p>在给定的TypedStringValue中解析目标类型</p>
* @param value the TypedStringValue to resolve -- 要解析的TypedStringValue
* @return the resolved target type (or {@code null} if none specified)
* -- 解析的目标类型(如果未指定,则未null)
* @throws ClassNotFoundException if the specified type cannot be resolved
* -- 如果无法解析指定的类型
* @see TypedStringValue#resolveTargetType
*/
@Nullable
protected Class<?> resolveTargetType(TypedStringValue value) throws ClassNotFoundException {
//如果value有携带目标类型
if (value.hasTargetType()) {
//返回value的目标类型
return value.getTargetType();
}
//从value中解析出目标类型
return value.resolveTargetType(this.beanFactory.getBeanClassLoader());
}
/**
* <p>解析出对应ref所封装的Bean元信息(即Bean名,Bean类型)的Bean对象:
* <ol>
* <li>定义用于一个存储bean对象的变量【变量 bean】</li>
* <li>获取另一个Bean引用的Bean类型【变量 beanType】</li>
* <li>如果引用来自父工厂:
* <ol>
* <li>获取父工厂【变量 parent】</li>
* <li>如果没有父工厂【parent】,抛出Bean创建异常</li>
* <li>如果beanType不为null,让bean引用 从父工厂中获取beanType对应的Bean对象</li>
* <li>否则,使用ref的Bean名,从父工厂中获取对应的Bean对像赋值给bean</li>
* </ol>
* </li>
* <li>否则:
* <ol>
* <li>定义一个用于存储解析出来的Bean名的变量【变量 resolvedName】</li>
* <li>如果beanType不为null:
* <ol>
* <li>解析与beanType唯一匹配的bean实例,包括其bean名【变量 namedBean】</li>
* <li>让bean引用nameBean所封装的Bean对象</li>
* <li>让resolvedName引用nameBean所封装的Bean名</li>
* </ol>
* </li>
* <li>否则:
* <ol>
* <li>让resolvedName引用经过解析ref所包装的Bean名后的Bean名</li>
* <li>获取resolvedName的Bean对象赋值给bean</li>
* </ol>
* </li>
* <li>如果Bean对象是NullBean实例,将bean置为null</li>
* <li>返回解析出来对应ref所封装的Bean元信息(即Bean名,Bean类型)的Bean对象【bean】</li>
* </ol>
* </li>
* <li>对整个方法步骤进行捕捉Bean包和子包中引发的所有异常(BeansException)【变量 ex】,
* 抛出Bean创建异常(BeanCreationException),包装ex.
* </li>
* </ol>
* </p>
* Resolve a reference to another bean in the factory.
* <p>在工厂中解决对另一个bean的引用</p>
* @param argName 为其定义值得参数名称
* @param ref 封装者另一个bean的引用的RuntimeBeanReference对象
*/
@Nullable
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
//定义用于一个存储bean对象的变量
Object bean;
//获取另一个Bean引用的Bean类型
Class<?> beanType = ref.getBeanType();
//如果引用来自父工厂
if (ref.isToParent()) {
//获取父工厂
BeanFactory parent = this.beanFactory.getParentBeanFactory();
//如果没有父工厂
if (parent == null) {
//抛出Bean创建异常:无法解析对bean的引用 ref 在父工厂中:没有可以的父工厂
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean " + ref +
" in parent factory: no parent factory available");
}
//如果引用的Bean类型不为null
if (beanType != null) {
//从父工厂中获取引用的Bean类型对应的Bean对象
bean = parent.getBean(beanType);
}
else {
//否则,使用引用的Bean名,从父工厂中获取对应的Bean对像
bean = parent.getBean(String.valueOf(doEvaluate(ref.getBeanName())));
}
}
else {
//定义一个用于存储解析出来的Bean名的变量
String resolvedName;
//如果beanType不为null
if (beanType != null) {
//解析与beanType唯一匹配的bean实例,包括其bean名
NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType);
//让bean引用nameBean所封装的Bean对象
bean = namedBean.getBeanInstance();
//让resolvedName引用nameBean所封装的Bean名
resolvedName = namedBean.getBeanName();
}
else {
//让resolvedName引用ref所包装的Bean名
resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
//获取resolvedName的Bean对象
bean = this.beanFactory.getBean(resolvedName);
}
//注册beanName与dependentBeanNamed的依赖关系到Bean工厂
this.beanFactory.registerDependentBean(resolvedName, this.beanName);
}
//如果Bean对象是NullBean实例
if (bean instanceof NullBean) {
//将bean置为null
bean = null;
}
//返回解析出来对应ref所封装的Bean元信息(即Bean名,Bean类型)的Bean对象
return bean;
}
//捕捉Bean包和子包中引发的所有异常
catch (BeansException ex) {
//抛出Bean创建异常,包装ex:设置argName时无法解析对bean'ref.getBeanName()'的引用
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}
/**
* <p>解析出内部Bean对象:
* <ol>
* <li>定义一个用于保存innerBd与beanDefinition合并后的BeanDefinition对象的变量【变量 mbd】</li>
* <li>让mbd引用innerBd与beanDefinition合并后的BeanDefinition对象</li>
* <li>【解决内部Bean名需要唯一的问题】:
* <ol>
* <li>定义实际的内部Bean名,初始为innerBeanName【变量 actualInnerBeanName】</li>
* <li>如果mbd配置成了单例,调整innerBeanName,直到该Bean名在工厂中唯一。最后将结果赋值给actualInnerBeanName</li>
* <li>将actualInnerBeanName和beanName的包含关系注册到该工厂中</li>
* </ol>
* </li>
* <li>【对内部Bean的依赖Bean进行初始化】:
* <ol>
* <li>获取mdb的要依赖的Bean名【变量 dependsOn】</li>
* <li>如果有需要依赖的Bean名【dependOn】:
* <ol>
* <li>遍历depensOn,元素名为dependsOnBean:
* <ol>
* <li>注册dependsOnBean与actualInnerBeanName的依赖关系到该工厂中</li>
* <li>获取dependsOnBean的Bean对像(不引用,只是为了让dependsOnBean所对应的Bean对象实例化)</li>
* </ol>
* </li>
* </ol>
* </li>
* </ol>
* </li>
* <li>【创建内部bean实例】:
* <ol>
* <li>创建actualInnerBeanName的Bean对象【变量 innerBean】</li>
* <li>如果innerBean时FactoryBean的实例:
* <ol>
* <li>mbds是否是"synthetic"的标记【变量 synthetic】。一般是指只有AOP相关的prointCut配置或者Advice配置才会
* 将synthetic设置为true</li>
* <li>从BeanFactory对象中获取管理的对象,只有mbd不是synthetic才对其对象进行该工厂的后置处理</li>
* </ol>
* </li>
* <li>如果innerBean是NullBean实例,将innerBean设置为null</li>
* </ol>
* </li>
* <li>返回actualInnerBeanName的Bean对象【innerBean】</li>
* <li>捕捉解析内部Bean对象过程中抛出的Bean包和子包中引发的所有异常【变量 ex】: 抛出Bean创建异常,引用ex</li>
* </ol>
* </p>
* Resolve an inner bean definition.
* <p>解析内部BeanDefinition</p>
* @param argName the name of the argument that the inner bean is defined for
* -- 为其定义内部Bean的参数名,即外层Bean的属性名
* @param innerBeanName the name of the inner bean
* -- 内部Bean名
* @param innerBd the bean definition for the inner bean
* -- 内部Bean的BeanDefinition
* @return the resolved inner bean instance
* -- 解析的内部Bean实例
*/
@Nullable
private Object resolveInnerBean(Object argName, String innerBeanName, BeanDefinition innerBd) {
//定义一个用于保存innerBd与beanDefinition合并后的BeanDefinition对象的变量
RootBeanDefinition mbd = null;
try {
//获取innerBd与beanDefinition合并后的BeanDefinition对象
mbd = this.beanFactory.getMergedBeanDefinition(innerBeanName, innerBd, this.beanDefinition);
// Check given bean name whether it is unique. If not already unique,
// add counter - increasing the counter until the name is unique.
// 检查给定的Bean名是否唯一。如果还不是唯一的,添加计数器-增加计数器,直到名称唯一为止.
//解决内部Bean名需要唯一的问题
//定义实际的内部Bean名,初始为innerBeanName
String actualInnerBeanName = innerBeanName;
//如果mbd配置成了单例
if (mbd.isSingleton()) {
//调整innerBeanName,直到该Bean名在工厂中唯一。最后将结果赋值给actualInnerBeanName
actualInnerBeanName = adaptInnerBeanName(innerBeanName);
}
//将actualInnerBeanName和beanName的包含关系注册到该工厂中
this.beanFactory.registerContainedBean(actualInnerBeanName, this.beanName);
// Guarantee initialization of beans that the inner bean depends on.
// 确保内部Bean依赖的Bean的初始化
//获取mdb的要依赖的Bean名
String[] dependsOn = mbd.getDependsOn();
//如果有需要依赖的Bean名
if (dependsOn != null) {
//遍历depensOn
for (String dependsOnBean : dependsOn) {
//注册dependsOnBean与actualInnerBeanName的依赖关系到该工厂中
this.beanFactory.registerDependentBean(dependsOnBean, actualInnerBeanName);
//获取dependsOnBean的Bean对像(不引用,只是为了让dependsOnBean所对应的Bean对象实例化)
this.beanFactory.getBean(dependsOnBean);
}
}
// Actually create the inner bean instance now...
// 实际上现有创建内部bean实例
// 创建actualInnerBeanName的Bean对象
Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null);
//如果innerBean时FactoryBean的实例
if (innerBean instanceof FactoryBean) {
//mbds是否是"synthetic"的标记。一般是指只有AOP相关的prointCut配置或者Advice配置才会将 synthetic设置为true
boolean synthetic = mbd.isSynthetic();
//从BeanFactory对象中获取管理的对象,只有mbd不是synthetic才对其对象进行该工厂的后置处理
innerBean = this.beanFactory.getObjectFromFactoryBean(
(FactoryBean<?>) innerBean, actualInnerBeanName, !synthetic);
}
//如果innerBean是NullBean实例
if (innerBean instanceof NullBean) {
//将innerBean设置为null
innerBean = null;
}
//返回actualInnerBeanName的Bean对象【innerBean】
return innerBean;
}
//捕捉解析内部Bean对象过程中抛出的Bean包和子包中引发的所有异常
catch (BeansException ex) {
//抛出Bean创建异常,引用ex:
// 在mdb不为null且mdb的Bean类名不为null的情况下,描述异常:无法创建类为[mdb的Bean类型名]的内部bean'innerBeanName'
// 否则,描述异常:设置argName时无法创建内部bean'innerBeanName'
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot create inner bean '" + innerBeanName + "' " +
(mbd != null && mbd.getBeanClassName() != null ? "of type [" + mbd.getBeanClassName() + "] " : "") +
"while setting " + argName, ex);
}
}
/**
* <p>调整Bean名,直到该Bean名在工厂中唯一.
* <ol>
* <li>定义一个实际内部Bean名变量,初始为innerBean名【变量 actualInnerBeanName】</li>
* <li>定义一个用于计数的计数器,初始为0【变量count】</li>
* <li>只要actualInnerBeanName是否已在该工厂中使用就继续循环:
* <ol>
* <li>计数器+1</li>
* <li>让actualInnerBeanName重新引用拼接后的字符串:innerBeanName+'#'+count</li>
* </ol>
* </li>
* <li>返回经过调整后的Bean名【变量 Bean】</li>
* </ol>
* </p>
* Checks the given bean name whether it is unique. If not already unique,
* a counter is added, increasing the counter until the name is unique.
* <p>检查给定Bean名是否唯一.如果还不是唯一的,则添加该计数器,直到名称唯一位置</p>
* @param innerBeanName the original name for the inner bean
* -- 内部Bean的原始名称
* @return the adapted name for the inner bean
* -- 内部Bean的调整后的最终Bean名
*/
private String adaptInnerBeanName(String innerBeanName) {
//定义一个实际内部Bean名变量,初始为innerBean名
String actualInnerBeanName = innerBeanName;
//定义一个用于计数的计数器,初始为0
int counter = 0;
//只要actualInnerBeanName是否已在该工厂中使用就继续循环,即actualInnerBeanName是否是别名
// 或该工厂是否已包含actualInnerBeanName的bean对象 或 该工厂是否已经为actualInnerBeanName注册了依赖Bean关系
while (this.beanFactory.isBeanNameInUse(actualInnerBeanName)) {
//计数器+1
counter++;
//让actualInnerBeanName重新引用拼接后的字符串:innerBeanName+'#'+count
actualInnerBeanName = innerBeanName + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR + counter;
}
//返回经过调整后的Bean名
return actualInnerBeanName;
}
/**
* <p>解析ManagedArray对象,以得到解析后的数组对象:
* <ol>
* <li>创建一个用于存放解析后的实例对象的elementType类型长度为ml大小的数组【变量 resolved】</li>
* <li>遍历ml(以fori形式):获取第i个ml元素对象,解析该元素对象的实例对象然后设置到第i个
* resolved元素中</li>
* <li>返回解析后的的数组对象【resolved】</li>
* </ol>
* </p>
* For each element in the managed array, resolve reference if necessary.
* <p>对于托管数组中的每个元素,如有必要,请解析引用</p>
*/
private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {
//创建一个用于存放解析后的实例对象的elementType类型长度为ml大小的数组
Object resolved = Array.newInstance(elementType, ml.size());
//遍历ml(以fori形式)
for (int i = 0; i < ml.size(); i++) {
//获取第i个ml元素对象,解析出该元素对象的实例对象然后设置到第i个resolved元素中
Array.set(resolved, i, resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
}
//返回解析后的的数组对象【resolved】
return resolved;
}
/**
* <p>解析ManagedList对象,以得到解析后的List对象:
* <ol>
* <li>定义一个用于存放解析后的实例对象的ArrayList,初始容量为ml大小【变量 resolved】</li>
* <li>遍历ml(以fori形式),获取第i个ml元素对象,解析该元素对象的实例对象然后添加到
* resolved中</li>
* <li>返回【resolved】</li>
* </ol>
* </p>
* For each element in the managed list, resolve reference if necessary.
* <p>对于托管列表中的每个元素,如有必要,请解析引用</p>
*/
private List<?> resolveManagedList(Object argName, List<?> ml) {
//定义一个用于存放解析后的实例对象的ArrayList,初始容量为ml大小
List<Object> resolved = new ArrayList<>(ml.size());
//遍历ml(以fori形式)
for (int i = 0; i < ml.size(); i++) {
//获取第i个ml元素对象,解析出该元素对象的实例对象然后添加到resolved中
resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
}
//返回【resolved】
return resolved;
}
/**
* <p>解析ManagedSet对象,以得到解析后的Set对象:
* <ol>
* <li>定义一个用于存放解析后的实例对象的LinkedHashSet,初始容量为ml大小【变量 resolved】</li>
* <li>定义一个遍历时的偏移量【变量 i】</li>
* <li>遍历ms,元素为m:
* <ol>
* <li>解析出该m的实例对象然后添加到resolved中</li>
* <li>偏移量+1【i】</li>
* </ol>
* </li>
* <li>返回resolved</li>
* </ol>
* </p>
* For each element in the managed set, resolve reference if necessary.
* <p>对于托管集中的每个元素,如有必要,请解析引用</p>
*/
private Set<?> resolveManagedSet(Object argName, Set<?> ms) {
//定义一个用于存放解析后的实例对象的LinkedHashSet,初始容量为ml大小
Set<Object> resolved = new LinkedHashSet<>(ms.size());
//定义一个遍历时的偏移量i
int i = 0;
//遍历ms,元素为m
for (Object m : ms) {
//解析出该m的实例对象然后添加到resolved中
resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));
//偏移量+1
i++;
}
//返回resolved
return resolved;
}
/**
* <p>解析ManagedMap对象,以得到解析后的Map对象:
* <ol>
* <li>定义用于存储解析后的key实例对象和value实例对象的LinkedHashMap,长度为mm的大小【变量 resolved】</li>
* <li>遍历mm,键名为key,值为value:
* <ol>
* <li>解析mm的key的实例对象【变量 resolvedKey】</li>
* <li>解析mm的value的实例对象【变量 resolvedValue】</li>
* <li>将解析出来的key和value的实例对象添加到resolved中</li>
* </ol>
* </li>
* <li>返回resolved</li>
* </ol>
* </p>
* For each element in the managed map, resolve reference if necessary.
* <p>对于托管映射中的每个元素,如有必要,请解析引用</p>
*/
private Map<?, ?> resolveManagedMap(Object argName, Map<?, ?> mm) {
//定义用于存储解析后的key实例对象和value实例对象的LinkedHashMap,长度为mm的大小
Map<Object, Object> resolved = new LinkedHashMap<>(mm.size());
//遍历mm
mm.forEach((key, value) -> {
//解析mm的key的实例对象
Object resolvedKey = resolveValueIfNecessary(argName, key);
//解析mm的value的实例对象
Object resolvedValue = resolveValueIfNecessary(new KeyedArgName(argName, key), value);
//将解析出来的key和value的实例对象添加到resolved中
resolved.put(resolvedKey, resolvedValue);
});
//返回resolved
return resolved;
}
/**
* Holder class used for delayed toString building.
* <p>用于延迟toString构建的Holder类</p>
*/
private static class KeyedArgName {
/**
* 参数名
*/
private final Object argName;
/**
* 键值
*/
private final Object key;
/**
* 新建一个KeyedArgName对象
* @param argName 参数名
* @param key 键值
*/
public KeyedArgName(Object argName, Object key) {
this.argName = argName;
this.key = key;
}
@Override
public String toString() {
return this.argName + " with key " + BeanWrapper.PROPERTY_KEY_PREFIX +
this.key + BeanWrapper.PROPERTY_KEY_SUFFIX;
}
}
}
Spring 5 BeanDefinitionValueResolver 源码注释
猜你喜欢
转载自blog.csdn.net/qq_30321211/article/details/108365617
今日推荐
周排行