概述
1、DirectFieldAccessor 介绍
DirectFieldAccessor 是 PropertyAccessor的实现类,可以直接获取实例的field。
2、集成的类图关系
3、源码分析
public class DirectFieldAccessor extends AbstractPropertyAccessor {
private final Object target;// 持有的目标对象
private final Map<String, Field> fieldMap = new HashMap<String, Field>();
/**
* Create a new DirectFieldAccessor for the given target object.
* @param target the target object to access
*/
public DirectFieldAccessor(final Object target) {
Assert.notNull(target, "Target object must not be null");
this.target = target;
ReflectionUtils.doWithFields(this.target.getClass(), new ReflectionUtils.FieldCallback() {
public void doWith(Field field) {
if (fieldMap.containsKey(field.getName())) {
// ignore superclass declarations of fields already found in a subclass
}
else {
fieldMap.put(field.getName(), field);// 将属性名 与 属性field域对应缓存起来
}
}
});
this.typeConverterDelegate = new TypeConverterDelegate(this, target);
registerDefaultEditors();
setExtractOldValueForEditor(true);
}
public boolean isReadableProperty(String propertyName) throws BeansException {
return this.fieldMap.containsKey(propertyName);
}
public boolean isWritableProperty(String propertyName) throws BeansException {
return this.fieldMap.containsKey(propertyName);
}
@Override
public Class<?> getPropertyType(String propertyName) throws BeansException {
Field field = this.fieldMap.get(propertyName);
if (field != null) {
return field.getType();//获取属性类型
}
return null;
}
public TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException {
Field field = this.fieldMap.get(propertyName);
if (field != null) {
return new TypeDescriptor(field);
}
return null;
}
@Override
public Object getPropertyValue(String propertyName) throws BeansException {
Field field = this.fieldMap.get(propertyName);
if (field == null) {
throw new NotReadablePropertyException(
this.target.getClass(), propertyName, "Field '" + propertyName + "' does not exist");
}
try {
ReflectionUtils.makeAccessible(field);
return field.get(this.target);// 通过反射执行 field 的 get 方法获取属性值
}
catch (IllegalAccessException ex) {
throw new InvalidPropertyException(this.target.getClass(), propertyName, "Field is not accessible", ex);
}
}
@Override
public void setPropertyValue(String propertyName, Object newValue) throws BeansException {
Field field = this.fieldMap.get(propertyName);
if (field == null) {
throw new NotWritablePropertyException(
this.target.getClass(), propertyName, "Field '" + propertyName + "' does not exist");
}
Object oldValue = null;
try {
ReflectionUtils.makeAccessible(field);
oldValue = field.get(this.target);
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
field.getName(), oldValue, newValue, field.getType(), new TypeDescriptor(field));
field.set(this.target, convertedValue);// 通过反射执行 field 的 set 方法获取属性值
}
catch (ConverterNotFoundException ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
throw new ConversionNotSupportedException(pce, field.getType(), ex);
}
catch (ConversionException ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
throw new TypeMismatchException(pce, field.getType(), ex);
}
catch (IllegalStateException ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
throw new ConversionNotSupportedException(pce, field.getType(), ex);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
throw new TypeMismatchException(pce, field.getType(), ex);
}
catch (IllegalAccessException ex) {
throw new InvalidPropertyException(this.target.getClass(), propertyName, "Field is not accessible", ex);
}
}
}
4、BeanWrapper & DirectFieldAccessor 的门面工厂 PropertyAccessorFactory
Spring 提供了获取BeanWrapper & DirectFieldAccessor 的门面工厂 PropertyAccessorFactory
(1)、PropertyAccessorFactory工厂内部提供了两个重要的方法,分别是获取 BeanWrapperImpl 、DirectFieldAccessor 的工具方法;
(2)、该类中的方法都是 public 静态的,Spring在定义类时限定为 abstract 类型,Spring的所有工具类均采用了这种抽象的定义方式,我们可以借鉴一下。
public abstract class PropertyAccessorFactory {
/**
* Obtain a BeanWrapper for the given target object,
* accessing properties in JavaBeans style.
* @param target the target object to wrap
* @return the property accessor
* @see BeanWrapperImpl
*/
public static BeanWrapper forBeanPropertyAccess(Object target) {
return new BeanWrapperImpl(target);
}
/**
* Obtain a PropertyAccessor for the given target object,
* accessing properties in direct field style.
* @param target the target object to wrap
* @return the property accessor
* @see DirectFieldAccessor
*/
public static ConfigurablePropertyAccessor forDirectFieldAccess(Object target) {
return new DirectFieldAccessor(target);
}
}
5、验证测试类
public class User {
private int id ;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHello(String name){
System.out.println("Hello " + name);
}
}
public class DirectFieldAccessorTest {
// Spring 提供的 DirectFieldAccessor 测试
@Test
public void testDirectFieldAccessor() {
User user = new User();
user.setId(1111);
user.setName("wangwu");
DirectFieldAccessor accessor = new DirectFieldAccessor(user);
TypeDescriptor id = accessor.getPropertyTypeDescriptor("id");
System.out.println(id.getName());
Object idValue = accessor.getPropertyValue("id");
System.out.println("idValue=========>" +idValue);
}
// Spring提供的门面工厂方法测试
@Test
public void testPropertyAccessorFactory() {
User user = new User();
user.setId(1111);
user.setName("wangwu");
ConfigurablePropertyAccessor configurablePropertyAccessor = PropertyAccessorFactory.forDirectFieldAccess(user);
//DirectFieldAccessor accessor = new DirectFieldAccessor(user);
TypeDescriptor id = configurablePropertyAccessor.getPropertyTypeDescriptor("id");
System.out.println(id.getName());
Object idValue = configurablePropertyAccessor.getPropertyValue("id");
System.out.println("idValue=========>" +idValue);
}
}
最后
以上就是着急路人为你收集整理的Spring 中 DirectFieldAccessor 类的使用的全部内容,希望文章能够帮你解决Spring 中 DirectFieldAccessor 类的使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复