[置顶] Spring 学习 (二)__BeanWrapper及其实现

Spring 中的 BeanWrapper BeanWrapper 允许以统一的方式访问 JavaBean 对象的属性,包括简单属性、复杂类型属性、集合和数组等。它支持通过属性路径(property path)来访问嵌套对象的属性,例如 person.address.streetName。BeanWrapper 是 Spring 框架中的一个接口,它提供了一种方式来设置和获取 JavaBean 的属性。JavaBean 是一种特殊的 Java 类,遵循特定的编码约定(例如,私有属性和公共的 getter/setter 方法),通常用于封装数据。 阅读详情
 

[置顶] Spring 学习 (二)__BeanWrapper及其实现

标签: springbeanobjectstringclassioc
  14840人阅读  评论(3)  收藏  举报
  分类:

目录(?)[+]

一、 BeanWrapper

BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器,由于BeanWrapper接口是PropertyAccessor的子接口,因此其也可以设置以及访问被包装对象的属性值。BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器可以用统一的方式来访问bean的属性。用户很少需要直接使用BeanWrapper进行编程。


二、 BeanWrapperImpl

BeanWrapperImpl类是对BeanWrapper接口的默认实现,它包装了一个bean对象,缓存了bean的内省结果,并可以访问bean的属性、设置bean的属性值。BeanWrapperImpl类提供了许多默认属性编辑器,支持多种不同类型的类型转换,可以将数组、集合类型的属性转换成指定特殊类型的数组或集合。用户也可以注册自定义的属性编辑器在BeanWrapperImpl中。

三、 BeanWrapper类图


四、 BeanWrapperImpl设置所包装的bean属性值序列图



五、 BeanWrapperImpl构造方法源码分析

5.1     BeanWrapperImpl构造方法

BeanWrapperImpl类有多个重载方法,下面的构造方法传入一个Object对象,此对象就是被BeanWrapperImpl类所包装的bean

[java]  view plain  copy
 print ?
  1. public BeanWrapperImpl(Object object) {  
  2.        registerDefaultEditors();  
  3.        setWrappedInstance(object);  
  4.     }  

构造方法的实现很简单,第一步在registerDefaultEditors()方法内部设置属性defaultEditorsActive值为true

第二步则调用setWrappedInstance(object)方法,进行初始化以及设置被包装的对象

5.2    setWrappedInstance(object)方法

此方法内部对BeanWrapperImpl类的一些重要属性进行了初始化,并创建了TypeConverterDelegate类的实例作为类型转换处理对象。在此之后,将对被包装bean进行内省分析,内省分析结果保存在cachedIntrospectionResults属性中,此属性是CachedIntrospectionResults类的实例.


5.3    CachedIntrospectionResults类

CachedIntrospectionResults类用于对对象的Class进行内省分析,保存对象的PropertyDescriptor信息,其静态方法

static CachedIntrospectionResults forClass(Class beanClass)

 throws BeansException

在BeanWrapperImpl类中被调用,用于对BeanWrapperImpl类所包装的bean进行内省分析,并返回内省分析结果给BeanWrapperImpl


六、 BeanWrapperImpl设置属性值源码分析

6.1                   setPropertyValue(PropertyValue pv)方法

BeanWrapperImpl类有多个设置bean属性值的重载方法,此处以

public void setPropertyValue(PropertyValue pv)

throws BeansException

方法作为说明。

[java]  view plain  copy
 print ?
  1. public void setPropertyValue(PropertyValue pv) throws BeansException {  
  2.        PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;  
  3.        if (tokens == null) {  
  4.            ……………..  
  5.             BeanWrapperImpl nestedBw = null;  
  6.            try {  
  7.               //根据属性名获取BeanWrapImpl对象,支持多重属性的递归分析处理  
  8.               nestedBw = getBeanWrapperForPropertyPath(propertyName);  
  9.            }  
  10.            catch ………..  
  11.            tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));  
  12.            //如果nestedBw等于this,则设置resolvedTokens属性值为tokens  
  13.            if (nestedBw == this) {  
  14.               pv.getOriginalPropertyValue().resolvedTokens = tokens;  
  15.            }  
  16.            nestedBw.setPropertyValue(tokens, pv);  
  17.        }  
  18.        else {  
  19.            setPropertyValue(tokens, pv);  
  20.        }  
  21.     }  

上述方法根据tokens变量是否为null,有两个不同的分支。其中当tokens为null时,则会对属性名进行递归调用分析处理,返回分析处理后的BeanWrapImpl对象nestedBw。如果nestedBw==this,则会设置pv的resolvedTokens属性值,最后将调用nestedBw对象的设置属性值方法设置属性

6.2                   getBeanWrapperForPropertyPath方法

getBeanWrapperForPropertyPath方法用于对属性名称(包括多重属性)进行处理,并返回BeanWrapperImpl对象。所支持的属性名称包括:多重属性(以.分隔)、数组集合map key属性(以[]方式)。

[java]  view plain  copy
 print ?
  1. protected BeanWrapperImpl getBeanWrapperForPropertyPath(String propertyPath) {  
  2.        //根据属性路径获取其第一个属性分隔符.的下标  
  3.        int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);  
  4.        //如果找到,则表示是有多重属性递归处理  
  5.        // Handle nested properties recursively.  
  6.        if (pos > -1) {  
  7.            //获取第一个属性分隔符前面的属性名称  
  8.            String nestedProperty = propertyPath.substring(0, pos);  
  9.            //获取第一个属性分隔符后面的字符串  
  10.            String nestedPath = propertyPath.substring(pos + 1);  
  11.            //获取第一个属性片断的BeanWrapperImpl对象nestedBw  
  12.            BeanWrapperImpl nestedBw = getNestedBeanWrapper(nestedProperty);  
  13.            //调用nestedBw的getBeanWrapperForPropertyPath方法,对第一个属性分隔符后面的属性字符串进行处理  
  14.            return nestedBw.getBeanWrapperForPropertyPath(nestedPath);  
  15.        }  
  16.        //否则,返回this对象本身  
  17.        else {  
  18.            return this;  
  19.        }  
  20.     }  

在此方法中对嵌套类型的属性进行了分析,首先将处理第一个.前的属性,获取nestedBw对象。然后再调用nestedBw对象的此方法递归处理第一个.后的其它属性,并返回处理结果。

       getNestedBeanWrapper(nestedProperty)方法则根据nestedProperty获取嵌套的BeanWrapperImpl对象。

6.3                   getPropertyNameTokens方法

getPropertyNameTokens方法内部用于对属性名全路径中最后一个.后的属性名称分析,返回PropertyTokenHolder对象。

6.4                   setPropertyValue(tokens, pv)方法

最终的设置属性的操作在此方法内部进行实现,此方法将最原始的属性值经过数组、集合类型属性的处理和类型转换后得到转换后值convertedValue,并从内省信息中获取操作此属性的方法writeMethod,用反射调用writeMethod将参数值convertedValue写入至被包装对象的目标属性中。至此BeanWrapperImpl的对象设值操作处理完成。

七、 BeanWrapperImpl对嵌套属性的支持

BeanWrapperImpl类通过其成员属性提供了一种支持嵌套属性的数据结构,下面是BeanWrapperImpl类的成员:

属性类型及名称

说明

Object object

被BeanWrapper包装的对象

String nestedPath

当前BeanWrapper对象所属嵌套层次的属性名,最顶层的BeanWrapper此属性的值为空

Object rootObject

最顶层BeanWrapper所包装的对象

Map nestedBeanWrappers

缓存当前BeanWrapper的下一层属性的nestedPath和对应的BeanWrapperImpl对象,此BeanWrapperImpl所包装的对应是属性nestedPath的值


例如有类:

Class Employee

{

        Company company;

       Card card;

    String name;

       String id;

    get/set方法

}

Class Company

{

        String companyName;

        Map<String,String> attrs;

get/set方法

}

Class Card

{

         ………….

}

嵌套属性:employee.company.attrs[“location”]

最顶层的BeanWrapper是employeeBeanWrapper,其包装的对象是employeeObj,nestedPath为空,rootObject也是employObj, employeeBeanWrapper里的nestedBeanWrappers则将包含以下的键值对:

“company”---àcompanyBeanWrapper

“card” ---àcardBeanWrapper

对于对象companyBeanWrapper,则其包装的对象则是companyObj,其nestedPath的值为company,rootObject为employeeObj, nestedBeanWrappers里面的值为空。

BeanWrapperImpl在调用方法

protected BeanWrapperImpl getBeanWrapperForPropertyPath(String propertyPath)

分析employee.company.attrs[“location”]属性值时,将先处理第一个点之前的属性employee得到顶层的BeanWrapper nestedBw,再调用nestedBw. getBeanWrapperForPropertyPath()方法递归处理第一个点后的其它属性,并最终返回所有属性段都分析后所产生的BeanWrapperImpl对象。

属性类型及名称

说明

String canonicalName

canonicalName为actualName再加上[key1][key2][key3]..这种形式

保存当前级别属性的实际名称,为[前的字符串

如属性employee.company.attrs[“location”]

在EmployeeBeanWrapperImpl类代表company属性,则canonicalName值为”company”

如在CompanyBeanWrapperImpl类代表attrs中key为location的属性,则其canonicalName为attrs[“location”]

 

String actualName

保存当前级别属性的实际名称,为[前的字符串

如属性employee.company.attrs[“location”]

在EmployeeBeanWrapperImpl类代表company属性,则actualName值为”company”

如在CompanyBeanWrapperImpl类代表attrs中key为location的属性,则其actualName为”attrs”,取当前属性级别中”[“前面的字符串

 

String[] keys

代表当前级别属性中所有位于[与]间的key或索引所组成的数组

注:“当前级别属性”表示所要访问在属性在属性全路径中位于..之间的值

九、 所使用到的工具类

在此过程中所使用到的一些工具类和主要方法如下:

org.springframework.beans.PropertyAccessorUtils  用于分析属性名称的工具类,提供分析嵌套属性、集合属性(包括.[]等)的一些工具方法。

源码解读之(七)BeanUtils(1) 就写到这了,也算是给这段时间的面试做一个总结,查漏补缺,祝自己好运吧,也希望正在求职或者打算跳槽的 程序员看到这个文章能有一点点帮助或收获,我就心满意足了。多思考,多问为什么。希望小伙伴们早点收到满意的offer!越努力越幸运!金九银十已经过了,就目前国内的面试模式来讲,在面试前积极的准备面试,复习整个 Java 知识体系将变得非常重要,可以很负责任的说一句,复习准备的是否充分,将直接影响你入职的成功率。 阅读详情

相关推荐

从零开始!在 Windows 上安装与配置 Dify

这篇博客将详细介绍如何在 Windows 系统上部署 Dify,适合零基础用户。从 Docker 和 WSL 的安装配置开始,逐步指导用户设置 Git、Docker 环境以及 Dify 配置文件,解决可能遇到的端口冲突等问题,最终完成 Dify 的启动和测试。通过简明易懂的步骤,帮助用户在本地成功运行 Dify,实现模型供应商配置,让 Dify 项目在 Windows 平台上顺利上线。

qq_49035156的博客 5万+

小明学Spring基础系列——Bean封装之BeanWrapper

从字面意思理解,Spring的BeanWrapper是对Spring Bean进行封装打包的类,在对Bean封装打包得到BeanWrapper对象之后,我们就可以通过BeanWrapper访问Bean的属性和方法

小明的博客 2136

【ros】ROS1的安装和相关使用方法

主要学习ros相关内容

Greary的博客 2379

Spring 学习 (二)__BeanWrapper及其实现

一、 BeanWrapper BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器,由于BeanWrapper接口是PropertyAccessor的子接口,因此其也可以设置以及访问被包装对象的属性值。BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器

小柒的专栏 5万+

OpenClaw Windows 最详细安装指南

Windows上养龙虾:OpenClaw完整安装教程+钉钉接入,助你养只大龙虾

weixin_43405859的博客 2212

SPAD 单光子雪崩二极管

SPAD,全称为,是一种高灵敏度的光电探测器件,能够在非常低的光照水平下检测单个光子。SPAD在工作时,当一个光子被探测器吸收后,能够触发一个雪崩效应,产生一个可以被检测到的电信号。

qq_42786033的博客 1万+

Spring官网阅读(十四)Spring中的BeanWrapper及类型转换

BeanWrapper是Spring中一个很重要的接口,Spring在通过配置信息创建对象时,第一步首先就是创建一个BeanWrapper。这篇文章我们就分析下这个接口,本文内容主要对应官网中的3.3及3.4小结 接口定义 // Spring低级JavaBeans基础设施的中央接口。通常来说并不直接使用BeanWrapper,而是借助BeanFactory或者DataBinder来一起使用,B...

做一个认真的程序员 8581

Spring IoC之BeanWrapper

文章目录概述BeanWrapper 简介BeanWrapper 使用场景BeanWrapper 的使用BeanWrapper 源码解析属性设置和获取定义属性设置和获取具体实现构造方法设置属性获取属性参考文献 概述 从上节 Spring IoC之ApplicationContext 解读完毕之后,关于 Spring IoC 中比较重要的5个组件我们已经分析完毕,但是这只是 IoC 容器涉及到的比较重...

Herishwater的博客 974

Android Audio常见问题分析方法

分析audio dump,确定写给BT的data是否正常,MTK平台Android原生架构分析threadloop write节点,高通平台分析QXDM 1586节点,从dump确定问题大概位置。分析systrace 确定性能。AudioFocus状态(用于播放或者音量异常的情况)。AudioTrack是否正常创建bt连接是否正常通路异常,setMode,setSpeakerphoneOn等都会影响设备选择,sco调用流程是否正常。

一条老狗的博客 2388

21天教你学会PCIe专栏(17)--多功能设备

1.1 定义多功能PCIe设备:多功能PCIe设备是指在一个物理设备中集成了多种功能的设备。这些功能可以通过不同的PCIe功能(Function)来实现,每个功能可以独立配置和管理。1.2 优点资源利用率:通过集成多种功能,减少物理设备的数量,提高资源利用率。成本效益:减少硬件成本和功耗,提高系统的经济性。灵活性:用户可以根据需要启用或禁用不同的功能,提高系统的灵活性。可扩展性:通过增加新的功能,扩展设备的功能,提高系统的可扩展性。1.3 应用场景网络设备。

xiaoheshang_123的博客 531

spring之BeanWrapper分析

1:spring bean生命周期分析 在这篇文章中我分析了spring bean的生命周期,为了方便本文的讲解,再来贴下生命周期的流程图: 我们看到图中有一步创建bean实例,对应的方法是createBeanInstance,调用位置源码如下: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean protected Object doCreateBean(final Strin

wang0907的博客 2060

7.1华为OD机试真题 新系统 - 仓库盘点 (Java/Py/C/C++/Js/Go)

7.1华为OD机试真题 新系统 - 仓库盘点 (Java/Py/C/C++/Js/Go)

算法大师! 507

Spring BeanWrapper

BeanWrapper这个接口主要用来操作一些标准的JavaBeans。对Bean属性的操作,封装了一个bean的行为,诸如设置和获取属性值等。大家熟知的主要有下面的工具类(Apache的BeanUtils和PropertyUtils、cglib的BeanMap和BeanCopier、spring的BeanUtils),但是Spring里有有一个更加强大的BeanWrapper操作类(支持设置嵌套...

江城宴的博客 811

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

BeanWrapper以及BeanWrapperImpl:Spring中处理Bean核心

BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器。BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器可以用统一的方式来访问bean的属性。用户很少需要直接使用BeanWrapper进行编程。BeanWrapper主要用于便捷地操作 JavaBean 的属性(如获取 / 设置属性值、处理嵌套属性、类型转换等)。

秃了也弱了 1256

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Spring之BeanWrapper和EL

Spring之BeanWrapper和EL BeanWrapper在Spring内部使用的地方非常多,因此有必要对其做简要的说明。另外Spring EL 是一种强大的表达式语音,支持在运行时对对象进行操作,这里也对其做简要说明。 BeanWrapper BeanWrapper接口及其实现,方便的提供了获取bean的属性,设置属性、获取属性描述的方法。 以下示例: System.out.p

我的山水 1405

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Spring之BeanWrapper

作用 BeanWrapper接口和它的实现BeanWrapperImpl是整个Spring框架最基本的类。它们利用反射机制(Reflection)和JavaBeans的标准提供一些对Java类属性的操作。其中最重要的操作是数据类型的转换和嵌套属性的引用(这使人联想起BeanUtils,OGNL和JSTL EL)。 源码 public interface BeanWrapper extends Co...

thebigdipperbdx的博客 569

Spring源码解析之-BeanWrapper分析

目录

一直打铁 1925

Spring5参考指南: BeanWrapper和PropertyEditor

文章目录BeanWrapperPropertyEditor BeanWrapper 通常来说一个Bean包含一个默认的无参构造函数,和属性的get,set方法。 org.springframework.beans 包里面有个很重要的类叫做BeanWrapper接口和他的实现BeanWrapperImpl,BeanWrapper提供了设置和获取属性值(单个或批量)、获取属性描述符和查询属性的功能,以...

程序那些事 1万+

Spring BeanWrapper应用

文章目录BeanWrapper应用场景复制对应对象的相应属性到另一个对象,并且保留之前的属性值BeanWrapper获取属性的方法 BeanWrapper 看看spring官网怎么说的: 解读 BeanWrapper可以获取,设置bean的属性 应用 像对象复制,一般会使用BeanUtils,BeanCopier等等 场景 但是对于一些特殊的情景就难以上手了,比如我现在有一个对象里面有些属性有值......

大鸡腿的博客 835

Spring为什么出现BeanWrapper

回顾 在前面几个章节,我们谈到SpringMVC参数绑定原理,以及javaBeans提供的数据绑定、数据转换PropertyEditor以及Spring提供的Converter转换器,或许读者有些疑问,为什么我们花了这么多精力去了解数据绑定、数据转换这类知识,今天我们就来了解Spring内部在哪里应用到了内建的数据处理,(这里并非指的是SpringMVC参数绑定) BeanWrapper public interface BeanWrapper extends ConfigurablePropert

qq_33468007的博客 624

Spring BeanWrapper 和Java BeanInfo实现对实体Getter和Setter操作

Spring BeanWrapper BeanWrapper是对Bean的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装bean的属性描述器,由于BeanWrapper接口是PropertyAccessor的子接口,因此其也可以设置以及访问被包装对象的属性值。BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spr...

换了马甲的小强的博客 1304

Spring中Bean的管理 – 使用BeanWrapper

Spring中Bean的管理 – 使用BeanWrapper 在Spring中,Bean的管理主要有3种方法,分别是使用BeanWrapper管理Bean、使用BeanFactory管理Bean和使用ApplicationContext管理Bean。 1、使用BeanWrapper管理Bean 在org.springframework.beans包中,还有两个非常重要的类:BeanW

ccecwg的专栏 1237

spring中强大的bean操作类BeanWrapper

对于bean属性的操作,大家熟知的主要有下面这些工具类: Apache的BeanUtils和PropertyUtilscglib的BeanMap和BeanCopierspring的BeanUtils 但是最近我发现,在spring中有一个更强大的操作bean的类BeanWrapper,它的强大体现在下面两个方面: 支持设置嵌套属性支持属性值的类型转换(设置Conversi

yycdaizi的专栏 9453

spring学习(六)——5.1 BeanWrapper

参考文章: http://www.iocoder.cn/ 实例化 Bean 阶段,我们从 BeanDefinition 得到的并不是我们最终想要的 Bean 实例,而是 BeanWrapper BeanWrapper 是 Spring 框架中重要的组件类,它就相当于一个代理类,Spring 委托 BeanWrapper 完成 Bean 属性的填充工作。在 Bean 实例被 Instant...

大风的博客 385
上一篇: Spring BeanWrapper分析
下一篇: java中重载与重写的区别
javaPie
博客等级 码龄16年 1171粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值