顾名思义它就是来创造一个WebDataBinder的工厂。
// @since 3.1 注意:WebDataBinder 可是1.2就有了~ public interface WebDataBinderFactory { // 此处使用的是Spring自己的NativeWebRequest 后面两个参数就不解释了 WebDataBinder createBinder(NativeWebRequest webRequest, @Nullable Object target, String objectName) throws Exception; }
它的继承树如下:
DefaultDataBinderFactory
public class DefaultDataBinderFactory implements WebDataBinderFactory { @Nullable private final WebBindingInitializer initializer; // 注意:这是唯一构造函数 public DefaultDataBinderFactory(@Nullable WebBindingInitializer initializer) { this.initializer = initializer; } // 实现接口的方法 @Override @SuppressWarnings("deprecation") public final WebDataBinder createBinder(NativeWebRequest webRequest, @Nullable Object target, String objectName) throws Exception { WebDataBinder dataBinder = createBinderInstance(target, objectName, webRequest); // 可见WebDataBinder 创建好后,此处就会回调(只有一个) if (this.initializer != null) { this.initializer.initBinder(dataBinder, webRequest); } // 空方法 子类去实现,比如InitBinderDataBinderFactory实现了词方法 initBinder(dataBinder, webRequest); return dataBinder; } // 子类可以复写,默认实现是WebRequestDataBinder // 比如子类ServletRequestDataBinderFactory就复写了,使用的new ExtendedServletRequestDataBinder(target, objectName) protected WebDataBinder createBinderInstance(@Nullable Object target, String objectName, NativeWebRequest webRequest) throws Exception return new WebRequestDataBinder(target, objectName); } }
按照Spring一贯的设计,本方法实现了模板动作,子类只需要复写对应的动作即可达到效果。
InitBinderDataBinderFactory
它继承自DefaultDataBinderFactory
,主要用于处理标注有@InitBinder
的方法做初始绑定~
// @since 3.1 public class InitBinderDataBinderFactory extends DefaultDataBinderFactory { // 需要注意的是:`@InitBinder`可以标注N多个方法~ 所以此处是List private final List<InvocableHandlerMethod> binderMethods; // 此子类的唯一构造函数 public InitBinderDataBinderFactory(@Nullable List<InvocableHandlerMethod> binderMethods, @Nullable WebBindingInitializer initializer) { super(initializer); this.binderMethods = (binderMethods != null ? binderMethods : Collections.emptyList()); } // 上面知道此方法的调用方法生initializer.initBinder之后 // 所以使用注解它生效的时机是在直接实现接口的后面的~ @Override public void initBinder(WebDataBinder dataBinder, NativeWebRequest request) throws Exception { for (InvocableHandlerMethod binderMethod : this.binderMethods) { // 判断@InitBinder是否对dataBinder持有的target对象生效~~~(根据name来匹配的) if (isBinderMethodApplicable(binderMethod, dataBinder)) { // 关于目标方法执行这块,可以参考另外一篇@InitBinder的原理说明~ Object returnValue = binderMethod.invokeForRequest(request, null, dataBinder); // 标注@InitBinder的方法不能有返回值 if (returnValue != null) { throw new IllegalStateException("@InitBinder methods must not return a value (should be void): " + binderMethod); } } } } //@InitBinder有个Value值,它是个数组。它是用来匹配dataBinder.getObjectName()是否匹配的 若匹配上了,现在此注解方法就会生效 // 若value为空,那就对所有生效~~~ protected boolean isBinderMethodApplicable(HandlerMethod initBinderMethod, WebDataBinder dataBinder) { InitBinder ann = initBinderMethod.getMethodAnnotation(InitBinder.class); Assert.state(ann != null, "No InitBinder annotation"); String[] names = ann.value(); return (ObjectUtils.isEmpty(names) || ObjectUtils.containsElement(names, dataBinder.getObjectName())); } }
ServletRequestDataBinderFactory
它继承自InitBinderDataBinderFactory,作用就更明显了。既能够处理@InitBinder,而且它使用的是更为强大的数据绑定器:ExtendedServletRequestDataBinder
// @since 3.1 public class ServletRequestDataBinderFactory extends InitBinderDataBinderFactory { public ServletRequestDataBinderFactory(@Nullable List<InvocableHandlerMethod> binderMethods, @Nullable WebBindingInitializer initializer) { super(binderMethods, initializer); } @Override protected ServletRequestDataBinder createBinderInstance( @Nullable Object target, String objectName, NativeWebRequest request) throws Exception { return new ExtendedServletRequestDataBinder(target, objectName); } }
此工厂是RequestMappingHandlerAdapter这个适配器默认使用的一个数据绑定器工厂,而RequestMappingHandlerAdapter却又是当下使用得最频繁、功能最强大的一个适配器
总结
WebDataBinder在SpringMVC中使用,它不需要我们自己去创建,我们只需要向它注册参数类型对应的属性编辑器PropertyEditor。PropertyEditor可以将字符串转换成其真正的数据类型,它的void setAsText(String text)方法实现数据转换的过程。
好好掌握这部分内容,这在Spring MVC中结合@InitBinder注解一起使用将有非常大的威力,能一定程度上简化你的开发,提高效率