java validation

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。java validation,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

spring boot项目中,使用hibernate validator作为java bean validation标准的一个实现。

https://docs.jboss.org/hibernate/validator/6.1/reference/en-US/html_single/

# 问题一:hibernate validator是如何注入进框架的?

我猜想应该也是通过bean注入的,于是去找hibernate autoconfigure相关代码,没找到。

网上也没搜到相关答案(估计是我关键字的问题)

在启动spring boot项目时,最开始显示的就是“background-preinit hibernate validator” 相关log。于是就顺着这个线索找了下去。

进入 org.springframework.boot.autoconfigure.BackgroundPreinitializer 这个类:

@Override
public void run() {
runSafely(new ConversionServiceInitializer());
runSafely(new ValidationInitializer());
runSafely(new MessageConverterInitializer());
runSafely(new JacksonInitializer());
runSafely(new CharsetInitializer());
preinitializationComplete.countDown();
}

继续追踪 new ValidationInitializer() :
private List<ValidationProvider<?>> loadProviders(ClassLoader classloader) {
ServiceLoader<ValidationProvider> loader = ServiceLoader.load( ValidationProvider.class, classloader );
Iterator<ValidationProvider> providerIterator = loader.iterator();
List<ValidationProvider<?>> validationProviderList = new ArrayList<>();
while ( providerIterator.hasNext() ) {
try {
validationProviderList.add( providerIterator.next() );
}
catch ( ServiceConfigurationError e ) {
// ignore, because it can happen when multiple
// providers are present and some of them are not class loader
// compatible with our API.
}
}
return validationProviderList;
}
这个函数返回的validationProviderList中的内容如下:

java validation

 此时已经加载了HibernateValidator类。找到关键点了。那么HibernateValidator是如何加载进来的呢?

    ServiceLoader<ValidationProvider> loader = ServiceLoader.load( ValidationProvider.class, classloader );

 

这里用到了Java SPI(Service Provider Interface)机制。

https://zhuanlan.zhihu.com/p/67665359

SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。

Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制,提供了通过interface寻找implement的方法。类似于IOC的思想,将装配的控制权移到程序之外,从而实现解耦。

适应场景:调用者根据需要,使用、扩展或替换实现策略。

使用Java SPI需要符合的约定:

  1. Service provider提供Interface的具体实现后,在目录META-INF/services下的文件(以Interface全路径命名)中添加具体实现类的全路径名;
  2. 接口实现类的jar包存放在使用程序的classpath中;
  3. 使用程序使用ServiceLoader动态加载实现类(根据目录META-INF/services下的配置文件找到实现类的全限定名并调用classloader来加载实现类到JVM);
  4. SPI的实现类必须具有无参数的构造方法。
几个关键点:
1、HibernateValidator的jar包需要放在classpath中。
spring boot项目中,通过引入spring-boot-starter-validation依赖,就把HibernateValidator jar包放入classpath了

2、HibernateValidator jar包中,在目录META-INF/services下,需要创建文件,文件名以Interface全路径命名,文件内容中添加具体实现类的全路径名

java validation

3、 使用ServiceLoader api加载ValidationProvider(Validation提供商,就是Hibernate) 

spring框架中使用

https://docs.spring.io/spring-framework/reference/core/validation/beanvalidation.html#validation-beanvalidation-spring-inject

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/203700.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!