Browse Source

Exclude FactoryBean implementation methods on CGLIB proxies as well

Issue: SPR-17374
pull/2005/head
Juergen Hoeller 7 years ago
parent
commit
dc1e3b4628
  1. 24
      spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/MethodValidationTests.java
  2. 19
      spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java
  3. 24
      spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java

24
spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/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));
}
@ -218,4 +227,17 @@ public class MethodValidationTests { @@ -218,4 +227,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;
}
}
}

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

@ -128,8 +128,23 @@ public class MethodValidationInterceptor implements MethodInterceptor { @@ -128,8 +128,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

@ -120,7 +120,16 @@ public class MethodValidationTests { @@ -120,7 +120,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));
}
@ -215,4 +224,17 @@ public class MethodValidationTests { @@ -215,4 +224,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