Spring番外篇-PropertyAccessor

1. PropertyAccessor的作用是什么

  • 通过key/value的形式为对象赋值属性
  • 通过字符串key访问对象属性

key:通常为字符串类型,支持嵌套属性访问下标访问
value: 任意类型

============================================================
PropertyAccessor又分为两种

  • 通过getter/setter访问属性 (BeanWrapper)
  • 通过字段直接访问 (DirectFieldAccessor)

2. BeanWrapper

BeanWrapper所有的属性操作都是调用getter/setter方法完成的

如果类定义了字段,但是没有getter和setter,那么无法为这个字段赋值

有一个Student类定义如下

    static class Student {

        private String name;

        private String firstName;

        private String lastName;

        private Student girlFriend;

        private List<Student> friends;

        public void setFirstName(String firstName) {
            this.firstName = firstName;
            this.name = firstName + (lastName == null ? "" : lastName);
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
            this.name = (firstName == null ? "" : firstName) + lastName;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setGirlFriend(Student girlFriend) {
            this.girlFriend = girlFriend;
        }

        public void setFriends(List<Student> friends) {
            this.friends = friends;
        }

        public String getName() {
            return name;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public Student getGirlFriend() {
            return girlFriend;
        }

        public List<Student> getFriends() {
            return friends;
        }
    }

使用BeanWrapper为对象赋值

    @Test
    public void bean_wrapper_tests() throws Exception {
		// 1. 创建对象
        Student lee = new Student();
		
		// 2. 创建BeanWrapper
        BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(lee);

		// 3. 赋值firstName
        wrapper.setPropertyValue("firstName", "Bruce");
		
		// 4. 验证: firstName 和 name 都有值
        assertEquals("Bruce", lee.firstName);
        assertEquals("Bruce", lee.name);
		
		// 5. 赋值lastName
        wrapper.setPropertyValue("lastName", "Lee");

		// 6. 验证: lastName 和 name 都有值
        assertEquals("Lee", lee.lastName);
        assertEquals("BruceLee", lee.name);

		// 7. 默认情况下, 是不允许使用嵌套属性赋值的
        assertThrows(NullValueInNestedPathException.class, () -> wrapper.setPropertyValue("girlFriend.firstName", "Linda"));
		
		// 8. 开启允许嵌套属性赋值
        wrapper.setAutoGrowNestedPaths(true);
		
		// 9. 给girlFriend赋值
        wrapper.setPropertyValue("girlFriend.firstName", "Linda");
        wrapper.setPropertyValue("girlFriend.lastName", "Emery");
		
		// 10. 验证: girlFriend有值, 且girlFriend.name有值
        assertNotNull(lee.girlFriend);
        assertEquals("LindaEmery", lee.girlFriend.name);
		
		// 11. 通过下标访问, 给friends:List 赋值
        wrapper.setPropertyValue("friends[0].name", "Bar");
        wrapper.setPropertyValue("friends[4].name", "Foo");
		
		// 12.1 验证: frientds的长度为5
        assertEquals(5, lee.friends.size());
		
		// 12.1 验证: friends[0].name
        assertEquals("Bar", lee.friends.get(0).name);
		
		// 12.3 验证: 跳过的3个索引都有值, 但是只是一个空对象
        for (int i = 1; i < 4; i++) {
            assertNotNull(lee.friends.get(i));
        }
	
		// 12.4 验证: friends[4].name
        assertEquals("Foo", lee.friends.get(4).name);
		
		// 13. 嵌套属性赋值
        wrapper.setPropertyValue("friends[0].friends[0].name", "Bar's friend");

		// 14. 验证
        assertEquals("Bar's friend", lee.getFriends().get(0).getFriends().get(0).name);
		
		// 15. 以json的格式打印对象
        Console.log(JSONUtil.toJsonStr(lee));
    }

执行完后,对象的json形式如下
在这里插入图片描述

3. DirectFieldAccessor

DirectFieldAccessor通过直接访问字段为属性赋值

    @Test
    public void direct_field_tests() throws Exception {
        // 1. 创建对象
        Student lee = new Student();

        // 2. 创建DirectFieldAccessor
        ConfigurablePropertyAccessor accessor = PropertyAccessorFactory.forDirectFieldAccess(lee);

        // 3. 赋值firstName
        accessor.setPropertyValue("firstName", "Bruce");
        // 3.1 验证: firstName有值
        assertEquals("Bruce", lee.firstName);
        // 3.2 验证: name为null
        assertNull(lee.name);

        // 4. 赋值lastName
        accessor.setPropertyValue("lastName", "Lee");
        // 4.1 验证: lastName有值
        assertEquals("Lee", lee.lastName);
        // 4.2 验证: name为null
        assertNull(lee.name);

        // 5. 以json的格式打印对象
        Console.log(JSONUtil.toJsonStr(lee));
    }

执行完后,对象的json形式如下
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
org.springframework.core-3.1.0是Spring框架的一个核心模块,用于提供核心的功能和工具。它包含了一些基础类和接口,用于支持Spring框架的其他模块的运行。 其中,org.springframework.core-3.1.0模块包括以下几个重要的功能: 1. 依赖注入机制:org.springframework.core-3.1.0提供了Spring框架中的依赖注入机制。通过使用它提供的注解和配置方式,可以实现对象之间的解耦和依赖关系的管理,从而降低代码的耦合度,提高代码的可重用性和可维护性。 2. 类型转换:org.springframework.core-3.1.0还提供了类型转换的功能。它包含了一些类型转换的工具类,可以方便地进行各种类型之间的转换操作,如字符串到数字的转换、日期类型的转换等。 3. 资源管理:org.springframework.core-3.1.0提供了资源管理的功能。它包含了一些基础的资源接口和实现类,用于加载和管理应用程序中的各种资源,如文件、URL、类路径下的资源等。 4. 注解处理:org.springframework.core-3.1.0还提供了注解处理的功能。它包含了一些注解处理的工具类和接口,可以方便地进行注解的解析和处理,实现一些特定的功能,如AOP切面、事务管理等。 总之,org.springframework.core-3.1.0是Spring框架中一个非常重要的核心模块,提供了许多基础的功能和工具,用于支持整个Spring框架的运行和扩展。它的存在为开发人员提供了便捷的开发方式和丰富的功能选择,提高了软件开发的效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值