Skip to content

Commit dc1e3b4

Browse files
committed
Exclude FactoryBean implementation methods on CGLIB proxies as well
Issue: SPR-17374
1 parent fa096dc commit dc1e3b4

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/MethodValidationTests.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,16 @@ private void doTestProxyValidation(MyValidInterface proxy) {
123123
@Test
124124
public void testLazyValidatorForMethodValidation() {
125125
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
126-
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class);
126+
LazyMethodValidationConfig.class, CustomValidatorBean.class,
127+
MyValidBean.class, MyValidFactoryBean.class);
128+
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
129+
}
130+
131+
@Test
132+
public void testLazyValidatorForMethodValidationWithProxyTargetClass() {
133+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
134+
LazyMethodValidationConfigWithProxyTargetClass.class, CustomValidatorBean.class,
135+
MyValidBean.class, MyValidFactoryBean.class);
127136
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
128137
}
129138

@@ -218,4 +227,17 @@ public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy
218227
}
219228
}
220229

230+
231+
@Configuration
232+
public static class LazyMethodValidationConfigWithProxyTargetClass {
233+
234+
@Bean
235+
public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) {
236+
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
237+
postProcessor.setValidator(validator);
238+
postProcessor.setProxyTargetClass(true);
239+
return postProcessor;
240+
}
241+
}
242+
221243
}

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,23 @@ public Object invoke(MethodInvocation invocation) throws Throwable {
128128

129129
private boolean isFactoryBeanMetadataMethod(Method method) {
130130
Class<?> clazz = method.getDeclaringClass();
131-
return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) &&
132-
!method.getName().equals("getObject"));
131+
132+
// Call from interface-based proxy handle, allowing for an efficient check?
133+
if (clazz.isInterface()) {
134+
return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) &&
135+
!method.getName().equals("getObject"));
136+
}
137+
138+
// Call from CGLIB proxy handle, potentially implementing a FactoryBean method?
139+
Class<?> factoryBeanType = null;
140+
if (SmartFactoryBean.class.isAssignableFrom(clazz)) {
141+
factoryBeanType = SmartFactoryBean.class;
142+
}
143+
else if (FactoryBean.class.isAssignableFrom(clazz)) {
144+
factoryBeanType = FactoryBean.class;
145+
}
146+
return (factoryBeanType != null && !method.getName().equals("getObject") &&
147+
ClassUtils.hasMethod(factoryBeanType, method.getName(), method.getParameterTypes()));
133148
}
134149

135150
/**

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,16 @@ private void doTestProxyValidation(MyValidInterface proxy) {
120120
@Test
121121
public void testLazyValidatorForMethodValidation() {
122122
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
123-
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class);
123+
LazyMethodValidationConfig.class, CustomValidatorBean.class,
124+
MyValidBean.class, MyValidFactoryBean.class);
125+
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
126+
}
127+
128+
@Test
129+
public void testLazyValidatorForMethodValidationWithProxyTargetClass() {
130+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
131+
LazyMethodValidationConfigWithProxyTargetClass.class, CustomValidatorBean.class,
132+
MyValidBean.class, MyValidFactoryBean.class);
124133
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
125134
}
126135

@@ -215,4 +224,17 @@ public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy
215224
}
216225
}
217226

227+
228+
@Configuration
229+
public static class LazyMethodValidationConfigWithProxyTargetClass {
230+
231+
@Bean
232+
public static MethodValidationPostProcessor methodValidationPostProcessor(@Lazy Validator validator) {
233+
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
234+
postProcessor.setValidator(validator);
235+
postProcessor.setProxyTargetClass(true);
236+
return postProcessor;
237+
}
238+
}
239+
218240
}

0 commit comments

Comments
 (0)