BeanWrapperImpl

PropertyEditorRegistry
PropertyEditorRegistrySupport
TypeConverter
TypeConverterSupport
PropertyAccessor
ConfigurablePropertyAccessor
AbstractPropertyAccessor
AbstractNestablePropertyAccessor
BeanWrapper
BeanWrapperImpl

它作为BeanWrapper接口的默认实现,它足以满足所有的典型应用场景,它会缓存Bean的内省结果而提高效率。

public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements BeanWrapper {

	// 缓存内省结果~
	@Nullable
	private CachedIntrospectionResults cachedIntrospectionResults;
	// The security context used for invoking the property methods.
	@Nullable
	private AccessControlContext acc;

	// 构造方法都是沿用父类的~
	public BeanWrapperImpl() {
		this(true);
	}
	... 
	private BeanWrapperImpl(Object object, String nestedPath, BeanWrapperImpl parent) {
		super(object, nestedPath, parent);
		setSecurityContext(parent.acc);
	}


	// @since 4.3  设置目标对象~~~
	public void setBeanInstance(Object object) {
		this.wrappedObject = object;
		this.rootObject = object;
		this.typeConverterDelegate = new TypeConverterDelegate(this, this.wrappedObject);
		// 设置内省的clazz
		setIntrospectionClass(object.getClass());
	}

	// 复写父类的方法  增加内省逻辑
	@Override
	public void setWrappedInstance(Object object, @Nullable String nestedPath, @Nullable Object rootObject) {
		super.setWrappedInstance(object, nestedPath, rootObject);
		setIntrospectionClass(getWrappedClass());
	}

	// 如果cachedIntrospectionResults它持有的BeanClass并不是传入的clazz 那就清空缓存 重新来~~~
	protected void setIntrospectionClass(Class<?> clazz) {
		if (this.cachedIntrospectionResults != null && this.cachedIntrospectionResults.getBeanClass() != clazz) {
			this.cachedIntrospectionResults = null;
		}
	}
	private CachedIntrospectionResults getCachedIntrospectionResults() {
		if (this.cachedIntrospectionResults == null) {
			// forClass此方法:生成此clazz的类型结果,并且缓存了起来~~
			this.cachedIntrospectionResults = CachedIntrospectionResults.forClass(getWrappedClass());
		}
		return this.cachedIntrospectionResults;
	}
	...

	// 获取到此属性的处理器。此处是个BeanPropertyHandler 内部类~
	@Override
	@Nullable
	protected BeanPropertyHandler getLocalPropertyHandler(String propertyName) {
		PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(propertyName);
		return (pd != null ? new BeanPropertyHandler(pd) : null);
	}
	@Override
	protected BeanWrapperImpl newNestedPropertyAccessor(Object object, String nestedPath) {
		return new BeanWrapperImpl(object, nestedPath, this);
	}
	@Override
	public PropertyDescriptor[] getPropertyDescriptors() {
		return getCachedIntrospectionResults().getPropertyDescriptors();
	}

	// 获取具体某一个属性的PropertyDescriptor 
	@Override
	public PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException {
		BeanWrapperImpl nestedBw = (BeanWrapperImpl) getPropertyAccessorForPropertyPath(propertyName);
		String finalPath = getFinalPath(nestedBw, propertyName);
		PropertyDescriptor pd = nestedBw.getCachedIntrospectionResults().getPropertyDescriptor(finalPath);
		if (pd == null) {
			throw new InvalidPropertyException(getRootClass(), getNestedPath() + propertyName, "No property '" + propertyName + "' found");
		}
		return pd;
	}
	...

	// 此处理器处理的是PropertyDescriptor 
	private class BeanPropertyHandler extends PropertyHandler {
		private final PropertyDescriptor pd;

		// 是否可读、可写  都是由PropertyDescriptor 去决定了~
		// java.beans.PropertyDescriptor~~
		public BeanPropertyHandler(PropertyDescriptor pd) {
			super(pd.getPropertyType(), pd.getReadMethod() != null, pd.getWriteMethod() != null);
			this.pd = pd;
		}
		...
		@Override
		@Nullable
		public Object getValue() throws Exception {
			...
			ReflectionUtils.makeAccessible(readMethod);
			return readMethod.invoke(getWrappedInstance(), (Object[]) null);
		}
		...
	}
}

从继承体系上,首先我们应该能看出来BeanWrapperImpl的三重身份:

  1. Bean包裹器
  2. 属性访问器(PropertyAccessor
  3. 属性编辑器注册表(PropertyEditorRegistry

从源码中继续分析还能再得出如下两个结论:

  1. 它给属性赋值调用的是Method方法,如readMethod.invokewriteMethod.invoke
  2. 它对Bean的操作,大都委托给CachedIntrospectionResults去完成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值