Unwrap Validator proxy for access to forExecutables (if necessary)
Issue: SPR-15807
This commit is contained in:
parent
17f42fc97a
commit
d1f42ac729
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -81,7 +81,7 @@ public class MethodValidationInterceptor implements MethodInterceptor {
|
|||
}
|
||||
|
||||
|
||||
private final Validator validator;
|
||||
private volatile Validator validator;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -116,7 +116,18 @@ public class MethodValidationInterceptor implements MethodInterceptor {
|
|||
|
||||
if (forExecutablesMethod != null) {
|
||||
// Standard Bean Validation 1.1 API
|
||||
Object execVal = ReflectionUtils.invokeMethod(forExecutablesMethod, this.validator);
|
||||
Object execVal;
|
||||
try {
|
||||
execVal = ReflectionUtils.invokeMethod(forExecutablesMethod, this.validator);
|
||||
}
|
||||
catch (AbstractMethodError err) {
|
||||
// Probably an adapter (maybe a lazy-init proxy) without BV 1.1 support
|
||||
Validator nativeValidator = this.validator.unwrap(Validator.class);
|
||||
execVal = ReflectionUtils.invokeMethod(forExecutablesMethod, nativeValidator);
|
||||
// If successful, store native Validator for further use
|
||||
this.validator = nativeValidator;
|
||||
}
|
||||
|
||||
Method methodToValidate = invocation.getMethod();
|
||||
Set<ConstraintViolation<?>> result;
|
||||
|
||||
|
@ -137,13 +148,11 @@ public class MethodValidationInterceptor implements MethodInterceptor {
|
|||
}
|
||||
|
||||
Object returnValue = invocation.proceed();
|
||||
|
||||
result = (Set<ConstraintViolation<?>>) ReflectionUtils.invokeMethod(validateReturnValueMethod,
|
||||
execVal, invocation.getThis(), methodToValidate, returnValue, groups);
|
||||
if (!result.isEmpty()) {
|
||||
throw new ConstraintViolationException(result);
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.validation.beanvalidation;
|
|||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.groups.Default;
|
||||
|
@ -26,6 +27,10 @@ import org.junit.Test;
|
|||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.AsyncAnnotationAdvisor;
|
||||
|
@ -64,7 +69,6 @@ public class MethodValidationTests {
|
|||
ac.close();
|
||||
}
|
||||
|
||||
|
||||
private void doTestProxyValidation(MyValidInterface proxy) {
|
||||
assertNotNull(proxy.myValidMethod("value", 5));
|
||||
try {
|
||||
|
@ -115,6 +119,13 @@ public class MethodValidationTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLazyValidatorForMethodValidation() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class);
|
||||
ctx.getBean(MyValidInterface.class).myValidMethod("value", 5);
|
||||
}
|
||||
|
||||
|
||||
@MyStereotype
|
||||
public static class MyValidBean implements MyValidInterface<String> {
|
||||
|
@ -165,4 +176,16 @@ public class MethodValidationTests {
|
|||
public @interface MyValid {
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
public static class LazyMethodValidationConfig {
|
||||
|
||||
@Bean
|
||||
public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) {
|
||||
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
|
||||
postProcessor.setValidator(validator);
|
||||
return postProcessor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.validation.hibernatevalidator5;
|
|||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.groups.Default;
|
||||
|
@ -26,11 +27,16 @@ import org.junit.Test;
|
|||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.AsyncAnnotationAdvisor;
|
||||
import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.validation.beanvalidation.CustomValidatorBean;
|
||||
import org.springframework.validation.beanvalidation.MethodValidationInterceptor;
|
||||
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
|
||||
|
||||
|
@ -68,7 +74,6 @@ public class MethodValidationTests {
|
|||
ac.close();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void doTestProxyValidation(MyValidInterface proxy) {
|
||||
assertNotNull(proxy.myValidMethod("value", 5));
|
||||
|
@ -120,6 +125,13 @@ public class MethodValidationTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLazyValidatorForMethodValidation() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
|
||||
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class);
|
||||
ctx.getBean(MyValidInterface.class).myValidMethod("value", 5);
|
||||
}
|
||||
|
||||
|
||||
@MyStereotype
|
||||
public static class MyValidBean implements MyValidInterface<String> {
|
||||
|
@ -170,4 +182,16 @@ public class MethodValidationTests {
|
|||
public @interface MyValid {
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
public static class LazyMethodValidationConfig {
|
||||
|
||||
@Bean
|
||||
public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) {
|
||||
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
|
||||
postProcessor.setValidator(validator);
|
||||
return postProcessor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue