diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java index f9c2efc169..3a3a6d0a54 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java @@ -30,6 +30,7 @@ import javax.validation.MessageInterpolator; import javax.validation.ParameterNameProvider; import javax.validation.TraversableResolver; import javax.validation.Validation; +import javax.validation.ValidationException; import javax.validation.ValidationProviderResolver; import javax.validation.Validator; import javax.validation.ValidatorContext; @@ -64,8 +65,12 @@ import org.springframework.util.ReflectionUtils; * you will almost always use the default Validator anyway. This can also be injected directly * into any target dependency of type {@link org.springframework.validation.Validator}! * - *
As of Spring 5.0, this class requires Bean Validation 1.1, with special support + *
As of Spring 5.0, this class requires Bean Validation 1.1+, with special support * for Hibernate Validator 5.x (see {@link #setValidationMessageSource}). + * This class is also runtime-compatible with Bean Validation 2.0 and Hibernate Validator 6.0, + * with one special note: If you'd like to call BV 2.0's {@code getClockProvider()} method, + * obtain the native {@code ValidatorFactory} through {@code #unwrap(ValidatorFactory.class)} + * and call the {@code getClockProvider()} method on the returned native reference there. * *
This class is also being used by Spring's MVC configuration namespace, in case of the
* {@code javax.validation} API being present but no explicit Validator having been configured.
@@ -293,7 +298,6 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
}
private void configureParameterNameProviderIfPossible(Configuration> configuration) {
- // TODO: inner class
final ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer;
final ParameterNameProvider defaultProvider = configuration.getDefaultParameterNameProvider();
configuration.parameterNameProvider(new ParameterNameProvider() {
@@ -359,6 +363,32 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
return this.validatorFactory.getParameterNameProvider();
}
+ // Bean Validation 2.0: currently not implemented here since it would imply
+ // a hard dependency on the new javax.validation.ClockProvider interface.
+ // To be resolved once Spring Framework requires Bean Validation 2.0+.
+ // Obtain the native ValidatorFactory through unwrap(ValidatorFactory.class)
+ // instead which will fully support a getClockProvider() call as well.
+ /*
+ @Override
+ public javax.validation.ClockProvider getClockProvider() {
+ Assert.notNull(this.validatorFactory, "No target ValidatorFactory set");
+ return this.validatorFactory.getClockProvider();
+ }
+ */
+
+ @Override
+ public Can be used as a programmatic wrapper. Also serves as base class for
* {@link CustomValidatorBean} and {@link LocalValidatorFactoryBean}.
*
+ * As of Spring Framework 5.0, this adapter is fully compatible with
+ * Bean Validation 1.1 as well as 2.0.
+ *
* @author Juergen Hoeller
* @since 3.0
*/
diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java
index 5cd539f971..e63a8fe224 100644
--- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java
+++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java
@@ -27,6 +27,7 @@ import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import javax.validation.Validation;
+import javax.validation.Validator;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
@@ -51,8 +52,9 @@ import static org.junit.Assert.*;
*/
public class SpringValidatorAdapterTests {
- private final SpringValidatorAdapter validatorAdapter = new SpringValidatorAdapter(
- Validation.buildDefaultValidatorFactory().getValidator());
+ private final Validator nativeValidator = Validation.buildDefaultValidatorFactory().getValidator();
+
+ private final SpringValidatorAdapter validatorAdapter = new SpringValidatorAdapter(nativeValidator);
private final StaticMessageSource messageSource = new StaticMessageSource();
@@ -66,6 +68,12 @@ public class SpringValidatorAdapterTests {
}
+ @Test
+ public void testUnwrap() {
+ Validator nativeValidator = validatorAdapter.unwrap(Validator.class);
+ assertSame(this.nativeValidator, nativeValidator);
+ }
+
@Test // SPR-13406
public void testNoStringArgumentValue() {
TestBean testBean = new TestBean();
diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java
index d292e041cf..56aaee72e2 100644
--- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java
+++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java
@@ -33,9 +33,12 @@ import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolation;
import javax.validation.Payload;
import javax.validation.Valid;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.HibernateValidator;
+import org.hibernate.validator.HibernateValidatorFactory;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -75,6 +78,12 @@ public class ValidatorFactoryTests {
fail("Invalid constraint violation with path '" + path + "'");
}
}
+
+ Validator nativeValidator = validator.unwrap(Validator.class);
+ assertTrue(nativeValidator.getClass().getName().startsWith("org.hibernate"));
+ assertTrue(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory);
+ assertTrue(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory);
+
validator.destroy();
}
@@ -96,6 +105,12 @@ public class ValidatorFactoryTests {
fail("Invalid constraint violation with path '" + path + "'");
}
}
+
+ Validator nativeValidator = validator.unwrap(Validator.class);
+ assertTrue(nativeValidator.getClass().getName().startsWith("org.hibernate"));
+ assertTrue(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory);
+ assertTrue(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory);
+
validator.destroy();
}
@@ -465,7 +480,7 @@ public class ValidatorFactoryTests {
String message() default "Should not be X";
- Class>[] groups() default { };
+ Class>[] groups() default {};
Class extends Payload>[] payload() default {};
}