23.自定义参数绑定原理

@Data
public class Person {
    
    private String userName;
    private Integer age;
    private Date birth;
    private Pet pet;
    
}
 
@Data
public class Pet {
 
    private String name;
    private String age;
 
}

form action="/saveuser" method="post">
    姓名:<input name="userName" value="zhangsan"><br/>
    年龄:<input name="age" value="18"><br/>
    生日:<input name="birth" value="2019/12/15"><br/>
    宠物姓名:<input name="pet.name" value="阿毛"><br/>
    宠物年龄:<input name="pet.age" value="3"><br/>
    <input type="submit" value="保存">
</form>
POJO封装过程:

1.是否支持解析

ServletModelAttributeMethodProcessor解析器解析

进入supportsArgumentResolver方法内,parameter.hasParameterAnnotation(ModelAttribute.class):是否有ModelAttribute注解,

我们没有加,进入第二个判断条件,

this.annotationNotRequired:true 这个注解不是必须的

BeanUtils.isSimpleProperty:是否是简单属性

进入isSimpleProperty方法查看怎么判断
isSimpleValueType(type):false
type.isArray():false
所以最终返回false
!BeanUtils.isSimpleProperty就为true

查看isSimpleValueType怎么判断,所以isSimpleValueType返回false

 

 

 2.如何解析

 进入到resolver.resolveArgument

name:person

parameter:在前面的 方法获取到了

ann:null,因为没有编住这个注解

createAttribute(name, parameter, binderFactory, webRequest):创建这个实例
attribute为空Person对象

webrequest:原生的request,
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);

:将原生request中的数据绑定到attribute里面

WebDataBinder :web数据绑定器,将请求参数的值绑定到指定的JavaBean里面

WebDataBinder 利用它里面的 Converters 将请求数据转成指定的数据类型。再次封装到JavaBean中

GenericConversionService:在设置每一个值的时候,找它里面的所有converter那个可以将这个数据类型(request带来参数的字符串)转换到指定的类型(JavaBean -- Integer)

byte -- > file

 bindRequestParameters(binder, webRequest):经过这一步,person里面就有值

进入查看如何绑定

 ------------------------------------

以下是绑定过程

进入servletBinder.bind(servletRequest),mpvs拿到请求参数对

addBindValues(mpvs, request):添加额外的绑定值

进入doBind方法 

 进入applyPropertyValues

 进入setPropertyValues,查看如何设置属性值

进入setPropertyValue

PropertyAccessor会拿到beanWrapper

然后调用wrapper这个setPropertyValue赋值,利用反射

 

 

进入processLocalProperty
convertForProperty():现在拿到的值是字符串,要转换成对应的类型

 

 

 进入convertForProperty

 

 

进入convertIfNeccssary,是否需要转换

进入this.typeConverterDelegate.convertIfNecessary

 conversionService.canConvert(sourceTypeDesc, typeDescriptor):查看能不能转化

进入canConvert,首先需要先拿到转换器,查看如何获取

进入getConverter,首先试图从缓存中拿,如果没有再从那124个转换器寻找 ,主要是利用增强for循环遍历

 

 然后一直放行到convert方法中,上一步已经通过getConverter得到了转换器

下一步看如何转换 

进入

ConversionUtils.invokeConverter(converter, source, sourceType, targetType)转换

 

进入

this.converterFactory.getConverter(targetType.getObjectType()).convert(source); 

 最终通过工厂进行转换

 

剩下的参数同样的过程 

posted @ 2022-08-08 10:56  随遇而安==  阅读(46)  评论(0编辑  收藏  举报