Spring读源码系列番外篇---01--PropertyValue相关类
引子
AbstractAutowireCapableBeanFactory类的doCreateBean方法里面的populateBean方法在对bean进行属性注入的时候用到了这个类
如果你想对增加自定义类型转换器,可能也需要去了解一下这方面的结构是怎么样的
@SuppressWarnings("deprecation")
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
return;
}
}
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
这里不是为了去讲bean的加载过程,因此这里不对上面的源码进行剖析,我这里只是将告诉大家,PropertyValue会在哪里被用到,那么下面就来进入PropertyValue的探索之路吧!!!
上面populateBean代码的解析参考: Spring读源码系列05----bean的加载—下
PropertyValue类继承图
AttributeAccessor–属性访问器—顶层接口
该类提供了统一的对BeanDefinition中属性的访问控制接口,通过观察其实现类,也可以发现这一点
public interface AttributeAccessor {
void setAttribute(String var1, @Nullable Object var2);
@Nullable
Object getAttribute(String var1);
default <T> T computeAttribute(String name, Function<String, T> computeFunction) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(computeFunction, "Compute function must not be null");
Object value = this.getAttribute(name);
if (value == null) {
value = computeFunction.apply(name);
Assert.state(value != null, () -> {
return String.format("Compute function must not return null for attribute named '%s'", name);
});
this.setAttribute(name, value);
}
return value;
}
@Nullable
Object removeAttribute(String var1);
boolean hasAttribute(String var1);
String[] attributeNames();
}
通过分析得知AttributeAccessor 主要提供对BeanDefinition里面属性的增删改查功能
AttributeAccessorSupport–属性访问器支持—实现了父类AttributeAccessor接口的功能
public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {
private final Map<String, Object> attributes = new LinkedHashMap();
public AttributeAccessorSupport() {
}
public void setAttribute(String name, @Nullable Object value) {
Assert.notNull(name, "Name must not be null");
if (value != null) {
this.attributes.put(name, value);
} else {
this.removeAttribute(name);
}
}
@Nullable
public Object getAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.get(name);
}
public <T> T computeAttribute(String name, Function<String, T> computeFunction) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(computeFunction, "Compute function must not be null");
Object value = this.attributes.computeIfAbsent(name, computeFunction);
Assert.state(value != null, () -> {
return String.format("Compute function must not return null for attribute named '%s'", name);
});
return value;
}
@Nullable
public Object removeAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.remove(name);
}
public boolean hasAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.containsKey(name);
}
public String[] attributeNames() {
return StringUtils.toStringArray(this.attributes.keySet());
}
protected void copyAttributesFrom(AttributeAccessor source) {
Assert.notNull(source, "Source must not be null");
String[] attributeNames = source.attributeNames();
String[] var3 = attributeNames;
int var4 = attributeNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String attributeName = var3[var5];
this.setAttribute(attributeName, source.getAttribute(attributeName));
}
}
public boolean equals(@Nullable Object other) {
return this == other || other instanceof AttributeAccessorSupport && this.attributes.equals(((AttributeAccessorSupport)other).attributes);
}
public int hashCode() {
return this.attributes.hashCode();
}
}
可以看出AttributeAccessorSupport只是对父类AttributeAccessor功能的简单实现,但是存放属性的集合时放在了该子类中,还新增了一个复制属性的方法
BeanMetadataElement —Bean 元数据元素—顶层接口
public interface BeanMetadataElement {
@Nullable
default Object getSource() {
return null;
}
}
如果是注解的话,这里我还没弄清楚,因此暂时无法给予解答,如果知道的小伙伴可以评论区留言
BeanMetadataAttributeAccessor—Bean 元数据属性访问器—实现了BeanMetadataElement 接口,继承了AttributeAccessorSupport
@SuppressWarnings("serial")
public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {
@Nullable
private Object source;
public void setSource(@Nullable Object source) {
this.source = source;
}
@Override
@Nullable
public Object getSource() {
return this.source;
}
public void addMetadataAttribute(BeanMetadataAttribute attribute) {
super.setAttribute(attribute.getName(), attribute);
}
@Nullable
public BeanMetadataAttribute getMetadataAttribute(String name) {
return (BeanMetadataAttribute) super.getAttribute(name);
}
@Override
public void setAttribute(String name, @Nullable Object value) {
super.setAttribute(name, new BeanMetadataAttribute(name, value));
}
@Override
@Nullable
public Object getAttribute(String name) {
BeanMetadataAttribute attribute = (BeanMetadataAttribute) super.getAttribute(name);
return (attribute != null ? attribute.getValue() : null);
}
@Override
@Nullable
public Object removeAttribute(String name) {
BeanMetadataAttribute attribute = (BeanMetadataAttribute) super.removeAttribute(name);
return (attribute != null ? attribute.getValue() : null);
}
}
BeanMetadataAttributeAccessor主要增加了元数据的访问和存储配置,以及通过BeanMetadataAttribute 来包装属性名和属性值的,并存放入父类AttributeAccessorSupport 的集合中去
BeanMetadataAttribute----Bean 元数据属性
该类实现了BeanMetadataElement接口,说明也会对元数据进行存储和crud
public class BeanMetadataAttribute implements BeanMetadataElement {
private final String name;
@Nullable
private final Object value;
@Nullable
private Object source;
public BeanMetadataAttribute(String name, @Nullable Object value) {
Assert.notNull(name, "Name must not be null");
this.name = name;
this.value = value;
}
public String getName() {
return this.name;
}
@Nullable
public Object getValue() {
return this.value;
}
public void setSource(@Nullable Object source) {
this.source = source;
}
@Override
@Nullable
public Object getSource() {
return this.source;
}
}
PropertyValue
@SuppressWarnings("serial")
public class PropertyValue extends BeanMetadataAttributeAccessor implements Serializable {
private final String name;
@Nullable
private final Object value;
private boolean optional = false;
private boolean converted = false;
@Nullable
private Object convertedValue;
@Nullable
volatile Boolean conversionNecessary;
@Nullable
transient volatile Object resolvedTokens;
public PropertyValue(String name, @Nullable Object value) {
Assert.notNull(name, "Name must not be null");
this.name = name;
this.value = value;
}
public PropertyValue(PropertyValue original) {
Assert.notNull(original, "Original must not be null");
this.name = original.getName();
this.value = original.getValue();
this.optional = original.isOptional();
this.converted = original.converted;
this.convertedValue = original.convertedValue;
this.conversionNecessary = original.conversionNecessary;
this.resolvedTokens = original.resolvedTokens;
setSource(original.getSource());
copyAttributesFrom(original);
}
public PropertyValue(PropertyValue original, @Nullable Object newValue) {
Assert.notNull(original, "Original must not be null");
this.name = original.getName();
this.value = newValue;
this.optional = original.isOptional();
this.conversionNecessary = original.conversionNecessary;
this.resolvedTokens = original.resolvedTokens;
setSource(original);
copyAttributesFrom(original);
}
public String getName() {
return this.name;
}
@Nullable
public Object getValue() {
return this.value;
}
public PropertyValue getOriginalPropertyValue() {
PropertyValue original = this;
Object source = getSource();
while (source instanceof PropertyValue && source != original) {
original = (PropertyValue) source;
source = original.getSource();
}
return original;
}
public void setOptional(boolean optional) {
this.optional = optional;
}
public boolean isOptional() {
return this.optional;
}
public synchronized boolean isConverted() {
return this.converted;
}
public synchronized void setConvertedValue(@Nullable Object value) {
this.converted = true;
this.convertedValue = value;
}
@Nullable
public synchronized Object getConvertedValue() {
return this.convertedValue;
}
}
PropertyValue只是对BeanDefinition中一个属性进行的封装,并且提供了是否在自动注入时忽略不存在属性的功能和是否进行类型转换的控制
一个bean一般会有多个属性,那么BeanDefinition肯定是通过一个集合来封装一组PropertyValue来表示这些属性,那么具体是什么样的集合呢?----看下面:
存放PropertyValue的集合
这里列出的是常用的,PropertyValues还有一些子类没列举出来
PropertyValues ---- 封装多个PropertyValue–顶层接口
public interface PropertyValues extends Iterable<PropertyValue> {
@Override
default Iterator<PropertyValue> iterator() {
return Arrays.asList(getPropertyValues()).iterator();
}
@Override
default Spliterator<PropertyValue> spliterator() {
return Spliterators.spliterator(getPropertyValues(), 0);
}
default Stream<PropertyValue> stream() {
return StreamSupport.stream(spliterator(), false);
}
PropertyValue[] getPropertyValues();
@Nullable
PropertyValue getPropertyValue(String propertyName);
PropertyValues changesSince(PropertyValues old);
boolean contains(String propertyName);
boolean isEmpty();
}
其实每个方法大概干啥的都可以猜出来,PropertyValues接口主要功能就是提供对PropertyValue集合的迭代器遍历方式
MutablePropertyValues----PropertyValues接口功能实现
@SuppressWarnings("serial")
public class MutablePropertyValues implements PropertyValues, Serializable {
private final List<PropertyValue> propertyValueList;
@Nullable
private Set<String> processedProperties;
private volatile boolean converted;
public MutablePropertyValues() {
this.propertyValueList = new ArrayList<>(0);
}
public MutablePropertyValues(@Nullable PropertyValues original) {
if (original != null) {
PropertyValue[] pvs = original.getPropertyValues();
this.propertyValueList = new ArrayList<>(pvs.length);
for (PropertyValue pv : pvs) {
this.propertyValueList.add(new PropertyValue(pv));
}
}
else {
this.propertyValueList = new ArrayList<>(0);
}
}
public MutablePropertyValues(@Nullable Map<?, ?> original) {
if (original != null) {
this.propertyValueList = new ArrayList<>(original.size());
original.forEach((attrName, attrValue) -> this.propertyValueList.add(
new PropertyValue(attrName.toString(), attrValue)));
}
else {
this.propertyValueList = new ArrayList<>(0);
}
}
public MutablePropertyValues(@Nullable List<PropertyValue> propertyValueList) {
this.propertyValueList =
(propertyValueList != null ? propertyValueList : new ArrayList<>());
}
public List<PropertyValue> getPropertyValueList() {
return this.propertyValueList;
}
public int size() {
return this.propertyValueList.size();
}
public MutablePropertyValues addPropertyValues(@Nullable PropertyValues other) {
if (other != null) {
PropertyValue[] pvs = other.getPropertyValues();
for (PropertyValue pv : pvs) {
addPropertyValue(new PropertyValue(pv));
}
}
return this;
}
public MutablePropertyValues addPropertyValues(@Nullable Map<?, ?> other) {
if (other != null) {
other.forEach((attrName, attrValue) -> addPropertyValue(
new PropertyValue(attrName.toString(), attrValue)));
}
return this;
}
public MutablePropertyValues addPropertyValue(PropertyValue pv) {
for (int i = 0; i < this.propertyValueList.size(); i++) {
PropertyValue currentPv = this.propertyValueList.get(i);
if (currentPv.getName().equals(pv.getName())) {
pv = mergeIfRequired(pv, currentPv);
setPropertyValueAt(pv, i);
return this;
}
}
this.propertyValueList.add(pv);
return this;
}
public void addPropertyValue(String propertyName, Object propertyValue) {
addPropertyValue(new PropertyValue(propertyName, propertyValue));
}
public MutablePropertyValues add(String propertyName, @Nullable Object propertyValue) {
addPropertyValue(new PropertyValue(propertyName, propertyValue));
return this;
}
public void setPropertyValueAt(PropertyValue pv, int i) {
this.propertyValueList.set(i, pv);
}
private PropertyValue mergeIfRequired(PropertyValue newPv, PropertyValue currentPv) {
Object value = newPv.getValue();
if (value instanceof Mergeable) {
Mergeable mergeable = (Mergeable) value;
if (mergeable.isMergeEnabled()) {
Object merged = mergeable.merge(currentPv.getValue());
return new PropertyValue(newPv.getName(), merged);
}
}
return newPv;
}
public void removePropertyValue(PropertyValue pv) {
this.propertyValueList.remove(pv);
}
public void removePropertyValue(String propertyName) {
this.propertyValueList.remove(getPropertyValue(propertyName));
}
@Override
public Iterator<PropertyValue> iterator() {
return Collections.unmodifiableList(this.propertyValueList).iterator();
}
@Override
public Spliterator<PropertyValue> spliterator() {
return Spliterators.spliterator(this.propertyValueList, 0);
}
@Override
public Stream<PropertyValue> stream() {
return this.propertyValueList.stream();
}
@Override
public PropertyValue[] getPropertyValues() {
return this.propertyValueList.toArray(new PropertyValue[0]);
}
@Override
@Nullable
public PropertyValue getPropertyValue(String propertyName) {
for (PropertyValue pv : this.propertyValueList) {
if (pv.getName().equals(propertyName)) {
return pv;
}
}
return null;
}
@Nullable
public Object get(String propertyName) {
PropertyValue pv = getPropertyValue(propertyName);
return (pv != null ? pv.getValue() : null);
}
@Override
public PropertyValues changesSince(PropertyValues old) {
MutablePropertyValues changes = new MutablePropertyValues();
if (old == this) {
return changes;
}
for (PropertyValue newPv : this.propertyValueList) {
PropertyValue pvOld = old.getPropertyValue(newPv.getName());
if (pvOld == null || !pvOld.equals(newPv)) {
changes.addPropertyValue(newPv);
}
}
return changes;
}
@Override
public boolean contains(String propertyName) {
return (getPropertyValue(propertyName) != null ||
(this.processedProperties != null && this.processedProperties.contains(propertyName)));
}
@Override
public boolean isEmpty() {
return this.propertyValueList.isEmpty();
}
public void registerProcessedProperty(String propertyName) {
if (this.processedProperties == null) {
this.processedProperties = new HashSet<>(4);
}
this.processedProperties.add(propertyName);
}
public void clearProcessedProperty(String propertyName) {
if (this.processedProperties != null) {
this.processedProperties.remove(propertyName);
}
}
public void setConverted() {
this.converted = true;
}
public boolean isConverted() {
return this.converted;
}
}
大体上就是提供了一个List集合用户保存PropertyValue,并且使用一个processedProperties集合记录当前正在处理的属性,然后还用一个convert变量,记录是否进行了类型转换
本篇文章只是简单介绍一下PropertyValue相关类是干啥的,但是这边并没有列出spring实际使用场景,一方面是因为水平有限,很多源码还没读过,另一方面也是篇幅原因,如果只是但拎出来讲的话,可能大部分人听不懂
|