-
Notifications
You must be signed in to change notification settings - Fork 38.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validator
factory methods with BiConsumer
#29890
Conversation
This commit introduces `of` method in `Validator` to provide a way to create a validator for the specific type `<T>` using `BiConsumer<T, Errors>` and define the validator in a functional way. This also eliminates the boilerplate for implementing the `supports` method.
spring-context/src/main/java/org/springframework/validation/Validator.java
Outdated
Show resolved
Hide resolved
spring-context/src/test/java/org/springframework/validation/DataBinderTests.java
Outdated
Show resolved
Hide resolved
spring-context/src/main/java/org/springframework/validation/Validator.java
Outdated
Show resolved
Hide resolved
A nice proposal to modernise I do find the usage of static <T> Validator of(Class<T> targetClass, BiConsumer<T, Errors> validator) {
return new Validator() {
@Override
public boolean supports(Class<?> clazz) {
return targetClass.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
validator.accept(targetClass.cast(target), errors);
}
};
} |
Validator
factory methods with BiConsumer
@making, We would like to make this part of Spring Framework 6.1. Are you ok with changing the PR to reflect our suggestions, or would you like me to pick it up from here? |
+1 for such functional approach in |
and make the `of` method return a `Validator`
@poutsma Updated the pr! |
That's a big improvement. 👍 |
Looking good! A couple of improvements that our team discussed before it can be merged in 6.1.
Let me know what you think about these suggestions. |
@poutsma I think it would make more sense to have a class like bellow, what do you think? class TypedValidator<T> implements Validator {
private final Class<T> targetClass;
private final BiPredicate<Class<T>, Class<?>> typeVerifier;
private final BiConsumer<T, Errors> delegate;
public TypedValidator(Class<T> targetClass, BiPredicate<Class<T>, Class<?>> classVerifier, BiConsumer<T, Errors> delegate) {
this.targetClass = targetClass;
this.typeVerifier = classVerifier;
this.delegate = delegate;
}
@Override
public boolean supports(Class<?> clazz) {
return this.typeVerifier.test(this.targetClass, clazz);
}
@Override
public void validate(Object target, Errors errors) {
this.delegate.accept(this.targetClass.cast(target), errors);
}
} and factory methods in static <T> Validator forInstanceOf(Class<T> targetClass, BiConsumer<T, Errors> delegate) {
return new TypedValidator<>(targetClass, Class::isAssignableFrom, delegate);
}
static <T> Validator forType(Class<T> targetClass, BiConsumer<T, Errors> delegate) {
return new TypedValidator<>(targetClass, Objects::equals, delegate);
} |
@making Sorry for not responding earlier. I'm liking that |
@poutsma package org.springframework.validation;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
class TypedValidator<T> implements Validator {
private final Class<T> targetClass;
private final Predicate<Class<?>> typeVerifier;
private final BiConsumer<T, Errors> delegate;
public TypedValidator(Class<T> targetClass, Predicate<Class<?>> typeVerifier, BiConsumer<T, Errors> delegate) {
this.targetClass = targetClass;
this.typeVerifier = typeVerifier;
this.delegate = delegate;
}
@Override
public boolean supports(Class<?> clazz) {
return this.typeVerifier.test(clazz);
}
@Override
public void validate(Object target, Errors errors) {
this.delegate.accept(this.targetClass.cast(target), errors);
}
} and static <T> Validator forType(Class<T> targetClass, BiConsumer<T, Errors> delegate) {
return new TypedValidator<>(targetClass, clazz -> Objects.equals(targetClass, clazz), delegate);
}
static <T> Validator forInstanceOf(Class<T> targetClass, BiConsumer<T, Errors> delegate) {
return new TypedValidator<>(targetClass, targetClass::isAssignableFrom, delegate);
} ? |
* gh-29890: Polish contribution Introduce functional factory methods in Validator
Thank you, @making, for submitting this PR. It has now been merged , see dd9f03d. I made some changes, including the Feel free to comment or create subsequent PRs if you have any further suggestions regarding this piece of functionality. |
- Split Validator::of into two factory methods: - forInstanceOf using Class::isAssignableFrom - forType using Class::equals - Moved anonymous implementation into TypedValidator with default access Closes gh-30341
This commit introduces
of
method inValidator
to provide a way to create a validator for the specific type<T>
usingBiConsumer<T, Errors>
and define the validator in a functional way.This also eliminates the boilerplate for implementing the
supports
method.BONUS: Supporting BiConsumer allows us to magically adapt 3rd party Validators (like YAVI) that return BiConsumer.
(I'm the creator of YAVI.)
(original proposal)
(revised version)