Insight Springmvc's validator谈谈程序可扩展实现策略
2017-01-10 18:50
441 查看
使用场景
如果需要在controller 校验bean,需要1.引入hibernate-validator 库;
2.Class 属性添加@NotNull、@Pattern、@Size限制条件;
3.controller 方法涉及到该Class入参添加@Valid,即可达到入参校验。
......
JSR-303
按照以往的惯例,spring 引入外部的支持,需要xml 进行对应的配置。hibernate-validator引入不用任何配置,就可以直接使用,是怎样的机制?首先,Springmvc bean-validation遵循JSR-303标准。策略:如果Springmvc 不配置validator,则根据当前环境存在JSR-303
api决定是否构造validator。
// 检测当前classpath是否存在 validation-api private static final boolean javaxValidationPresent = ClassUtils.isPresent("javax.validation.Validator", AnnotationDrivenBeanDefinitionParser.class.getClassLoader()); private RuntimeBeanReference getValidator(Element element, Object source, ParserContext parserContext) { if (element.hasAttribute("validator")) { // 配置指定的validator return new RuntimeBeanReference(element.getAttribute("validator")); } else if (javaxValidationPresent) { // 当前classpath 有可用的JSR-303 实现,关键!!! RootBeanDefinition validatorDef = new RootBeanDefinition("org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"); //... String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef); return new RuntimeBeanReference(validatorName); } else { // 默认无可用的validator return null; } }
然后,LocalValidatorFactoryBean 会在初始化过程构造default-validatorFactory,得到hibernate-validator。
......
java.util.ServiceLoader
如何得到Validator 接口的实现类,或者说扫描当前classpath,加载默认的实现类。这个就依赖jdk提供的ServiceLoader,功能类似bean-factory.getBean(name, requiredType)。/** * 构造ServiceLoader,find符合指定接口的实现类 */ private List> loadProviders(ClassLoader classloader) { ServiceLoader loader = ServiceLoader.load(ValidationProvider.class, classloader); Iterator providerIterator = loader.iterator(); List> validationProviderList = new ArrayList>(); while (providerIterator.hasNext()) { try { validationProviderList.add(providerIterator.next()); } catch (ServiceConfigurationError e) { // ... } } return validationProviderList; }
......
总结
程序的可扩展性实现方案:1.程序本身已支持插件库的应用,根据运行环境,确定是否启用,类似springmvc启用默认校验的实现;
2.程序本身支持标准的api,利用ServiceLoader实现插件库的替换,类似hibernate-validator的集成。
......
More
Insight ServiceLoader look-up指定接口的Implement 实现// service provider(Implement) 必须配置在指定的路径下,才会被遍历! private static final String PREFIX = "META-INF/services/"; public boolean hasNext() { try { // fullname = META-INF/services/ + 指定接口的全名 String fullName = PREFIX + service.getName(); // 当前loader加载扫描到的文件,解析文件得到Implement's name configs = loader.getResources(fullName); pending = parse(service, configs.nextElement()); } catch (IOException x) { fail(service, "Error locating configuration files", x); } nextName = pending.next(); return true; } public S next() { String cn = nextName; try { // 根据上一步解析到的Implement's name,得到Implement's instance S p = service.cast(Class.forName(cn, true, loader).newInstance()); 4000 providers.put(cn, p); return p; } catch (ClassNotFoundException x) { fail(service, "Provider " + cn + " not found"); } }
相关文章推荐
- 基于SpringMVC+hibernate-validator实现实现动态签名验证
- SpringMVC+Spring+mybatis+redis项目从零开始--redis缓存策略和配置实现
- 微信小程序 websocket 实现SpringMVC+Spring+Mybatis
- SpringMVC+Spring+mybatis+redis项目从零开始--redis缓存策略和配置实现
- MVC程序实现Autocomplete功能 扩展
- 实现定时任务,包括修改执行策略,用quartz+Spring
- 一个用Spring AOP实现异常处理和记录程序执行时间的实例(一)
- spring WEB MVC + Spring + hibernate开发web程序的配置说明和简单实例的详细说明
- 5.11 一个用Spring AOP实现异常处理和记录程序执行时间的实例
- hibernate+spring实现分页程序
- ASP.NET MVC 使用总结(二)——扩展HtmlHelper实现动态生成title及meta
- 网络蜘蛛程序的设计与实现(二)网页抓取策略
- 粗谈Spring与Struts的整合——从实现的Struts的扩展点上看Spring与Struts的整合
- ASP.NET MVC 使用总结(二)——扩展HtmlHelper实现动态生成title及meta
- 搭建你的Spring.Net+Nhibernate+Asp.Net Mvc 框架 (三)实现数据库接口层和业务逻辑层
- 一个用Spring AOP实现异常处理和记录程序执行时间的实例(二)
- 实现类似“添加扩展程序…”的设计时支持
- 程序优化的实现策略。
- 用Shell扩展实现源代码统计程序(转)
- Asp.net MVC 用户在线简单实现及单点登陆扩展(一)