Hi,
we noticed in one of our loadtests that a substantial amount of "hidden" NoSuchMethodException
s is being thrown when using @javax.validation.Valid
on controller methods.
@PostMapping("test")
public void test(@RequestBody @Valid @NotNull TestRequest request) {
// Some code
}
This is caused by calling AnnotationUtils.getValue()
on this annotation, which has no such property. This PR bypasses the annotation utility call. I also took the freedom to refactor this logic into a common place in ValidationUtils
to avoid copy-paste throughout the different modules.
An isolated JMH benchmark shows the following results when dealing with @Valid
:
Benchmark Mode Cnt Score Error Units
MyBenchmark.testNew avgt 10 6,253 ± 0,312 ns/op
MyBenchmark.testOld avgt 10 1761,995 ± 92,262 ns/op
As a workaround you can use org.springframework.validation.annotation.Validated
of course, but I would prefer not to have such a drawback when using javax.validation.Valid
.
Let me know what you think.
Cheers, Christoph
Comment From: jhoeller
Hey @dreis2211 it's indeed worth handling the common javax.annotation.Valid
case explicitly there, and also worth extracting the evaluation logic. However, it'll have to be a new org.springframework.validation.annotation.ValidationAnnotationUtils
class in order to avoid a package cycle, since it refers to the Validated
annotation in the subpackage there. If you could refactor it that way with a since
marker for 5.3.7, we'd be happy to roll it in...
Comment From: dreis2211
@jhoeller Thanks for the review. I just committed the requested changes.
Comment From: snicoll
@dreis2211 I can see ModelAttributeMethodProcessorTests
is failing. Can you please have a look?
Comment From: dreis2211
@snicoll Should be fixed - I was a bit overly ambitious and wanted to optimize the custom @Valid
annotations case as well, which broke when the annotation was defined as an inner class.
Comment From: snicoll
Thanks for the follow-up Christoph.