我是靠谱客的博主 着急路人,最近开发中收集的这篇文章主要介绍Spring 中 DirectFieldAccessor 类的使用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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 类的使用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部