Browse Source

Exclude FactoryBean implementation methods on CGLIB proxies as well

Issue: SPR-17374

(cherry picked from commit dc1e3b4628)
pull/22320/head
Juergen Hoeller 7 years ago
parent
commit
6711515ef5
  1. 19
      spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java
  2. 24
      spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java
  3. 24
      spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/MethodValidationTests.java

19
spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java

@ -171,8 +171,23 @@ public class MethodValidationInterceptor implements MethodInterceptor { @@ -171,8 +171,23 @@ public class MethodValidationInterceptor implements MethodInterceptor {
private boolean isFactoryBeanMetadataMethod(Method method) {
Class<?> clazz = method.getDeclaringClass();
return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) &&
!method.getName().equals("getObject"));
// Call from interface-based proxy handle, allowing for an efficient check?
if (clazz.isInterface()) {
return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) &&
!method.getName().equals("getObject"));
}
// Call from CGLIB proxy handle, potentially implementing a FactoryBean method?
Class<?> factoryBeanType = null;
if (SmartFactoryBean.class.isAssignableFrom(clazz)) {
factoryBeanType = SmartFactoryBean.class;
}
else if (FactoryBean.class.isAssignableFrom(clazz)) {
factoryBeanType = FactoryBean.class;
}
return (factoryBeanType != null && !method.getName().equals("getObject") &&
ClassUtils.hasMethod(factoryBeanType, method.getName(), method.getParameterTypes()));
}
/**

24
spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java

@ -123,7 +123,16 @@ public class MethodValidationTests { @@ -123,7 +123,16 @@ public class MethodValidationTests {
@Test
public void testLazyValidatorForMethodValidation() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class);
LazyMethodValidationConfig.class, CustomValidatorBean.class,
MyValidBean.class, MyValidFactoryBean.class);
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
}
@Test
public void testLazyValidatorForMethodValidationWithProxyTargetClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
LazyMethodValidationConfigWithProxyTargetClass.class, CustomValidatorBean.class,
MyValidBean.class, MyValidFactoryBean.class);
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
}
@ -223,4 +232,17 @@ public class MethodValidationTests { @@ -223,4 +232,17 @@ public class MethodValidationTests {
}
}
@Configuration
public static class LazyMethodValidationConfigWithProxyTargetClass {
@Bean
public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
postProcessor.setValidator(validator);
postProcessor.setProxyTargetClass(true);
return postProcessor;
}
}
}

24
spring-orm-hibernate4/src/test/java/org/springframework/validation/hibernatevalidator5/MethodValidationTests.java

@ -127,7 +127,16 @@ public class MethodValidationTests { @@ -127,7 +127,16 @@ public class MethodValidationTests {
@Test
public void testLazyValidatorForMethodValidation() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class);
LazyMethodValidationConfig.class, CustomValidatorBean.class,
MyValidBean.class, MyValidFactoryBean.class);
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
}
@Test
public void testLazyValidatorForMethodValidationWithProxyTargetClass() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
LazyMethodValidationConfigWithProxyTargetClass.class, CustomValidatorBean.class,
MyValidBean.class, MyValidFactoryBean.class);
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
}
@ -227,4 +236,17 @@ public class MethodValidationTests { @@ -227,4 +236,17 @@ public class MethodValidationTests {
}
}
@Configuration
public static class LazyMethodValidationConfigWithProxyTargetClass {
@Bean
public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
postProcessor.setValidator(validator);
postProcessor.setProxyTargetClass(true);
return postProcessor;
}
}
}

Loading…
Cancel
Save