Spring @InitBinder注解如何使用


这篇文章主要讲解了“Spring@InitBinder注解如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring@InitBinder注解如何使用”吧!以前言中提到的字符串转Date为例,对@InitBinder的使用进行说明。上面写好了一个简单的Controller,用于获取Date并存储。然后在单元测试中使用TestRestTemplate模拟客户端向服务端发起请求,程序如下。由于此时并没有使用@InitBinder注解修饰的方法向WebDataBinder注册CustomDateEditor对象,运行测试程序时断言会无法通过,报错会包含如下信息。Failed to convert value of type ‘java.lang.String’ to required type ‘java.util.Date’由于无法将字符串转换为Date,导致了参数类型不匹配的异常。下面使用@ControllerAdvice注解和@InitBinder注解为WebDataBinder添加CustomDateEditor对象,使SpringMVC框架为我们实现字符串转Date。此时再执行测试程序,断言通过。小节:由@InitBinder注解修饰的方法返回值类型必须为void,入参必须为WebDataBinder对象实例。如果在@Controller注解修饰的类中使用@InitBinder注解则配置仅对当前类生效,如果在@ControllerAdvice注解修饰的类中使用@InitBinder注解则配置全局生效。现在假如需要将日期字符串转换为LocalDate,但是SpringMVC框架并没有提供类似于CustomDateEditor这样的Editor时,可以通过继承PropertyEditorSupport类来实现自定义Editor。首先看如下的一个Controller。同样的在单元测试中使用TestRestTemplate模拟客户端向服务端发起请求。此时直接执行测试程序断言会不通过,会报错类型转换异常。现在实现一个自定义的Editor。CustomLocalDateEditor是自定义的Editor,最简单的情况下,通过继承PropertyEditorSupport并重写setAsText() 方法可以实现一个自定义Editor。通常,自定义的转换逻辑在setAsText() 方法中实现,并将转换后的值通过调用父类PropertyEditorSupport的setValue() 方法完成设置。同样的,使用@ControllerAdvice注解和@InitBinder注解为WebDataBinder添加CustomLocalDateEditor对象。此时再执行测试程序,断言全部通过。小节:通过继承PropertyEditorSupport类并重写setAsText()方法可以实现一个自定义Editor。已经知道,由@InitBinder注解修饰的方法用于初始化WebDataBinder,并且在详解SpringMVC-RequestMappingHandlerAdapter这篇文章中提到:从request获取到handler方法中由@RequestParam注解或@PathVariable注解修饰的参数后,便会使用WebDataBinderFactory工厂完成对WebDataBinder的初始化。下面看一下具体的实现。AbstractNamedValueMethodArgumentResolver#resolveArgument部分源码如下所示。实际上,上面方法中的binderFactory是ServletRequestDataBinderFactory工厂类,该类的类图如下所示。createBinder() 是由接口WebDataBinderFactory声明的方法,ServletRequestDataBinderFactory的父类DefaultDataBinderFactory对其进行了实现,实现如下。initBinder() 是DefaultDataBinderFactory的一个模板方法,InitBinderDataBinderFactory对其进行了重写,如下所示。如上,initBinder() 方法中会遍历加载的所有由@InitBinder注解修饰的方法并执行,从而完成对WebDataBinder的初始化。小节:WebDataBinder的初始化是由WebDataBinderFactory先创建WebDataBinder实例,然后遍历WebDataBinderFactory加载好的由@InitBinder注解修饰的方法并执行,以完成WebDataBinder的初始化。由第三小节可知,WebDataBinder的初始化是由WebDataBinderFactory先创建WebDataBinder实例,然后遍历WebDataBinderFactory加载好的由@InitBinder注解修饰的方法并执行,以完成WebDataBinder的初始化。本小节将学习WebDataBinderFactory如何加载由@InitBinder注解修饰的方法。WebDataBinderFactory的获取是发生在RequestMappingHandlerAdapter的invokeHandlerMethod() 方法中,在该方法中是通过调用getDataBinderFactory() 方法获取WebDataBinderFactory。下面看一下其实现。RequestMappingHandlerAdapter#getDataBinderFactory源码如下所示。上面的方法中使用到了两个缓存,initBinderCache和initBinderAdviceCache,表示如下。其中initBinderCache的key是handler的Class对象,value是handler的initBinder方法集合,initBinderCache一开始是没有值的,当需要获取handler对应的initBinder方法集合时,会先从initBinderCache中获取,如果获取不到才会调用MethodIntrospector#selectMethods方法获取,然后再将获取到的handler对应的initBinder方法集合缓存到initBinderCache中。initBinderAdviceCache的key是ControllerAdviceBean,value是ControllerAdviceBean的initBinder方法集合,initBinderAdviceCache的值是在RequestMappingHandlerAdapter初始化时调用的afterPropertiesSet() 方法中完成加载的,具体的逻辑在详解SpringMVC-RequestMappingHandlerAdapter有详细说明。因此WebDataBinderFactory中的initBinder方法由两部分组成,一部分是写在当前handler中的initBinder方法(这解释了为什么写在handler中的initBinder方法仅对当前handler生效),另外一部分是写在由@ControllerAdvice注解修饰的类中的initBinder方法,所有的这些initBinder方法均会对WebDataBinderFactory创建的WebDataBinder免费云主机域名对象进行初始化。最后,看一下createDataBinderFactory() 的实现。RequestMappingHandlerAdapter#createDataBinderFactoryServletRequestDataBinderFactory#ServletRequestDataBinderFactoryInitBinderDataBinderFactory#InitBinderDataBinderFactory可以发现,最终创建的WebDataBinderFactory实际上是ServletRequestDataBinderFactory,并且在执行ServletRequestDataBinderFactory的构造函数时,会调用其父类InitBinderDataBinderFactory的构造函数,在这个构造函数中,会将之前获取到的生效范围内的initBinder方法赋值给InitBinderDataBinderFactory的binderMethods变量,最终完成了initBinder方法的加载。小节:由@InitBinder注解修饰的方法的加载发生在创建WebDataBinderFactory时,在创建WebDataBinderFactory之前,会先获取对当前handler生效的initBinder方法集合,然后在创建WebDataBinderFactory的构造函数中将获取到的initBinder方法集合加载到WebDataBinderFactory中。感谢各位的阅读,以上就是“Spring@InitBinder注解如何使用”的内容了,经过本文的学习后,相信大家对Spring@InitBinder注解如何使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是百云主机,小编将为大家推送更多相关知识点的文章,欢迎关注!

相关推荐: Elasticsearch的删除映射类型怎么操作

这篇文章主要讲解了“Elasticsearch的删除映射类型怎么操作”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Elasticsearch的删除映射类型怎么操作”吧!在elasticsearch7.0.0或更…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 05/21 17:08
Next 05/21 17:15

相关推荐