Skip to content

Commit 76a1c6b

Browse files
dangzhicairangwilkinsona
authored andcommitted
Provide callback mechanism for customizing validation configuration
See gh-29429
1 parent f3aa5d0 commit 76a1c6b

File tree

4 files changed

+163
-2
lines changed

4 files changed

+163
-2
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
package org.springframework.boot.autoconfigure.validation;
1818

19+
import java.util.List;
20+
1921
import jakarta.validation.Validator;
2022
import jakarta.validation.executable.ExecutableValidator;
23+
import jakarta.validation.valueextraction.ValueExtractor;
2124

2225
import org.springframework.beans.factory.ObjectProvider;
2326
import org.springframework.beans.factory.config.BeanDefinition;
@@ -28,8 +31,11 @@
2831
import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
2932
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
3033
import org.springframework.boot.validation.MessageInterpolatorFactory;
34+
import org.springframework.boot.validation.beanvalidation.CustomizableLocalValidatorFactoryBean;
3135
import org.springframework.boot.validation.beanvalidation.FilteredMethodValidationPostProcessor;
3236
import org.springframework.boot.validation.beanvalidation.MethodValidationExcludeFilter;
37+
import org.springframework.boot.validation.beanvalidation.customize.AddValueExtractorCustomizer;
38+
import org.springframework.boot.validation.beanvalidation.customize.Customizer;
3339
import org.springframework.context.ApplicationContext;
3440
import org.springframework.context.annotation.Bean;
3541
import org.springframework.context.annotation.Import;
@@ -53,11 +59,20 @@
5359
@Import(PrimaryDefaultValidatorPostProcessor.class)
5460
public class ValidationAutoConfiguration {
5561

62+
@Bean
63+
public static AddValueExtractorCustomizer autoAddValueExtractorCustomizer(
64+
@SuppressWarnings({ "rawtypes", "unchecked" }) List<ValueExtractor> valueExtractors) {
65+
66+
return new AddValueExtractorCustomizer(valueExtractors);
67+
}
68+
5669
@Bean
5770
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
5871
@ConditionalOnMissingBean(Validator.class)
59-
public static LocalValidatorFactoryBean defaultValidator(ApplicationContext applicationContext) {
60-
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
72+
public static LocalValidatorFactoryBean defaultValidator(ApplicationContext applicationContext,
73+
List<Customizer> customizers) {
74+
CustomizableLocalValidatorFactoryBean factoryBean = new CustomizableLocalValidatorFactoryBean();
75+
factoryBean.setCustomizers(customizers);
6176
MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory(applicationContext);
6277
factoryBean.setMessageInterpolator(interpolatorFactory.getObject());
6378
return factoryBean;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.validation.beanvalidation;
18+
19+
import java.util.List;
20+
import java.util.Optional;
21+
22+
import jakarta.validation.Configuration;
23+
24+
import org.springframework.boot.validation.beanvalidation.customize.Customizer;
25+
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
26+
27+
/**
28+
* This class will callback the {@link Customizer} which supply by application. For
29+
* example:
30+
*
31+
* <pre>{@code
32+
* &#64;Bean
33+
* public Customizer customizer() {
34+
* return configuration -> {
35+
* configuration.addValueExtractor(new CustomResultValueExtractor());
36+
* configuration.xxx
37+
* ...
38+
* };
39+
* }
40+
* }</pre>
41+
*
42+
* @author Dang Zhicairang
43+
* @since 2.6.2
44+
*/
45+
public class CustomizableLocalValidatorFactoryBean extends LocalValidatorFactoryBean {
46+
47+
private List<Customizer> customizers;
48+
49+
public void setCustomizers(List<Customizer> customizers) {
50+
this.customizers = customizers;
51+
}
52+
53+
@Override
54+
protected void postProcessConfiguration(Configuration<?> configuration) {
55+
Optional.ofNullable(this.customizers)
56+
.ifPresent((list) -> list.forEach((customizer) -> customizer.customize(configuration)));
57+
}
58+
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.validation.beanvalidation.customize;
18+
19+
import java.util.List;
20+
import java.util.Optional;
21+
22+
import jakarta.validation.Configuration;
23+
import jakarta.validation.valueextraction.ValueExtractor;
24+
25+
/**
26+
* Add given collection of {@link ValueExtractor} into {@link Configuration}.
27+
*
28+
* @author Dang Zhicairang
29+
* @since 2.6.2
30+
*/
31+
@SuppressWarnings({ "rawtypes", "unchecked" })
32+
public class AddValueExtractorCustomizer implements Customizer {
33+
34+
private List<ValueExtractor> valueExtractors;
35+
36+
public AddValueExtractorCustomizer(List<ValueExtractor> valueExtractors) {
37+
this.valueExtractors = valueExtractors;
38+
}
39+
40+
public List<ValueExtractor> getValueExtractors() {
41+
return this.valueExtractors;
42+
}
43+
44+
public void setValueExtractors(List<ValueExtractor> valueExtractors) {
45+
this.valueExtractors = valueExtractors;
46+
}
47+
48+
@Override
49+
public void customize(Configuration<?> configuration) {
50+
Optional.ofNullable(this.getValueExtractors())
51+
.ifPresent((list) -> list.forEach(configuration::addValueExtractor));
52+
}
53+
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2012-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.validation.beanvalidation.customize;
18+
19+
import jakarta.validation.Configuration;
20+
21+
/**
22+
* Callback interface that can be used to customize {@link Configuration}.
23+
*
24+
* @author Dang Zhicairang
25+
* @since 2.6.2
26+
* @see AddValueExtractorCustomizer
27+
*/
28+
@FunctionalInterface
29+
public interface Customizer {
30+
31+
void customize(Configuration<?> configuration);
32+
33+
}

0 commit comments

Comments
 (0)