Skip to content

Commit 5f2d47a

Browse files
committed
MethodValidationInterceptor excludes FactoryBean metadata methods
Issue: SPR-17374
1 parent 2255d22 commit 5f2d47a

File tree

3 files changed

+80
-7
lines changed

3 files changed

+80
-7
lines changed

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

+33-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
2727

2828
import org.springframework.aop.framework.ProxyFactory;
2929
import org.springframework.beans.MutablePropertyValues;
30+
import org.springframework.beans.factory.FactoryBean;
3031
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3132
import org.springframework.context.annotation.Bean;
3233
import org.springframework.context.annotation.Configuration;
@@ -122,8 +123,8 @@ private void doTestProxyValidation(MyValidInterface proxy) {
122123
@Test
123124
public void testLazyValidatorForMethodValidation() {
124125
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
125-
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class);
126-
ctx.getBean(MyValidInterface.class).myValidMethod("value", 5);
126+
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class);
127+
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
127128
}
128129

129130

@@ -146,6 +147,35 @@ public String myGenericMethod(String value) {
146147
}
147148

148149

150+
@MyStereotype
151+
public static class MyValidFactoryBean implements FactoryBean<String>, MyValidInterface<String> {
152+
153+
@Override
154+
public String getObject() {
155+
return null;
156+
}
157+
158+
@Override
159+
public Class<?> getObjectType() {
160+
return String.class;
161+
}
162+
163+
@Override
164+
public Object myValidMethod(String arg1, int arg2) {
165+
return (arg2 == 0 ? null : "value");
166+
}
167+
168+
@Override
169+
public void myValidAsyncMethod(String arg1, int arg2) {
170+
}
171+
172+
@Override
173+
public String myGenericMethod(String value) {
174+
return value;
175+
}
176+
}
177+
178+
149179
public interface MyValidInterface<T> {
150180

151181
@NotNull Object myValidMethod(@NotNull(groups = MyGroup.class) String arg1, @Max(10) int arg2);

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,6 +28,8 @@
2828
import org.aopalliance.intercept.MethodInterceptor;
2929
import org.aopalliance.intercept.MethodInvocation;
3030

31+
import org.springframework.beans.factory.FactoryBean;
32+
import org.springframework.beans.factory.SmartFactoryBean;
3133
import org.springframework.core.BridgeMethodResolver;
3234
import org.springframework.core.annotation.AnnotationUtils;
3335
import org.springframework.util.ClassUtils;
@@ -86,6 +88,11 @@ public MethodValidationInterceptor(Validator validator) {
8688
@Override
8789
@SuppressWarnings("unchecked")
8890
public Object invoke(MethodInvocation invocation) throws Throwable {
91+
// Avoid Validator invocation on FactoryBean.getObjectType/isSingleton
92+
if (isFactoryBeanMetadataMethod(invocation.getMethod())) {
93+
return invocation.proceed();
94+
}
95+
8996
Class<?>[] groups = determineValidationGroups(invocation);
9097

9198
// Standard Bean Validation 1.1 API
@@ -119,6 +126,12 @@ public Object invoke(MethodInvocation invocation) throws Throwable {
119126
return returnValue;
120127
}
121128

129+
private boolean isFactoryBeanMetadataMethod(Method method) {
130+
Class<?> clazz = method.getDeclaringClass();
131+
return ((clazz == FactoryBean.class || clazz == SmartFactoryBean.class) &&
132+
!method.getName().equals("getObject"));
133+
}
134+
122135
/**
123136
* Determine the validation groups to validate against for the given method invocation.
124137
* <p>Default are the validation groups as specified in the {@link Validated} annotation

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

+33-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
2727

2828
import org.springframework.aop.framework.ProxyFactory;
2929
import org.springframework.beans.MutablePropertyValues;
30+
import org.springframework.beans.factory.FactoryBean;
3031
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3132
import org.springframework.context.annotation.Bean;
3233
import org.springframework.context.annotation.Configuration;
@@ -119,8 +120,8 @@ private void doTestProxyValidation(MyValidInterface proxy) {
119120
@Test
120121
public void testLazyValidatorForMethodValidation() {
121122
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
122-
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class);
123-
ctx.getBean(MyValidInterface.class).myValidMethod("value", 5);
123+
LazyMethodValidationConfig.class, CustomValidatorBean.class, MyValidBean.class, MyValidFactoryBean.class);
124+
ctx.getBeansOfType(MyValidInterface.class).values().forEach(bean -> bean.myValidMethod("value", 5));
124125
}
125126

126127

@@ -143,6 +144,35 @@ public String myGenericMethod(String value) {
143144
}
144145

145146

147+
@MyStereotype
148+
public static class MyValidFactoryBean implements FactoryBean<String>, MyValidInterface<String> {
149+
150+
@Override
151+
public String getObject() {
152+
return null;
153+
}
154+
155+
@Override
156+
public Class<?> getObjectType() {
157+
return String.class;
158+
}
159+
160+
@Override
161+
public Object myValidMethod(String arg1, int arg2) {
162+
return (arg2 == 0 ? null : "value");
163+
}
164+
165+
@Override
166+
public void myValidAsyncMethod(String arg1, int arg2) {
167+
}
168+
169+
@Override
170+
public String myGenericMethod(String value) {
171+
return value;
172+
}
173+
}
174+
175+
146176
public interface MyValidInterface<T> {
147177

148178
@NotNull Object myValidMethod(@NotNull(groups = MyGroup.class) String arg1, @Max(10) int arg2);

0 commit comments

Comments
 (0)