|
45 | 45 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
46 | 46 | import org.springframework.core.Ordered;
|
47 | 47 | import org.springframework.core.PriorityOrdered;
|
| 48 | +import org.springframework.core.annotation.AnnotatedElementUtils; |
48 | 49 | import org.springframework.core.annotation.AnnotationUtils;
|
49 | 50 | import org.springframework.core.convert.ConversionService;
|
50 | 51 | import org.springframework.core.convert.converter.Converter;
|
|
61 | 62 | import org.springframework.util.StringUtils;
|
62 | 63 | import org.springframework.validation.Errors;
|
63 | 64 | import org.springframework.validation.Validator;
|
| 65 | +import org.springframework.validation.annotation.Validated; |
64 | 66 | import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
65 | 67 |
|
66 | 68 | /**
|
@@ -362,8 +364,8 @@ private Validator getValidator() {
|
362 | 364 | return this.validator;
|
363 | 365 | }
|
364 | 366 | if (this.localValidator == null && isJsr303Present()) {
|
365 |
| - this.localValidator = new LocalValidatorFactory() |
366 |
| - .run(this.applicationContext); |
| 367 | + this.localValidator = new ValidatedLocalValidatorFactoryBean( |
| 368 | + this.applicationContext); |
367 | 369 | }
|
368 | 370 | return this.localValidator;
|
369 | 371 | }
|
@@ -394,18 +396,38 @@ private ConversionService getDefaultConversionService() {
|
394 | 396 | }
|
395 | 397 |
|
396 | 398 | /**
|
397 |
| - * Factory to create JSR 303 LocalValidatorFactoryBean. Inner class to prevent class |
398 |
| - * loader issues. |
| 399 | + * {@link LocalValidatorFactoryBean} supports classes annotated with |
| 400 | + * {@link Validated @Validated}. |
399 | 401 | */
|
400 |
| - private static class LocalValidatorFactory { |
401 |
| - |
402 |
| - public Validator run(ApplicationContext applicationContext) { |
403 |
| - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); |
404 |
| - MessageInterpolatorFactory interpolatorFactory = new MessageInterpolatorFactory(); |
405 |
| - validator.setApplicationContext(applicationContext); |
406 |
| - validator.setMessageInterpolator(interpolatorFactory.getObject()); |
407 |
| - validator.afterPropertiesSet(); |
408 |
| - return validator; |
| 402 | + private static class ValidatedLocalValidatorFactoryBean |
| 403 | + extends LocalValidatorFactoryBean { |
| 404 | + |
| 405 | + private static final Log logger = LogFactory |
| 406 | + .getLog(ConfigurationPropertiesBindingPostProcessor.class); |
| 407 | + |
| 408 | + ValidatedLocalValidatorFactoryBean(ApplicationContext applicationContext) { |
| 409 | + setApplicationContext(applicationContext); |
| 410 | + setMessageInterpolator(new MessageInterpolatorFactory().getObject()); |
| 411 | + afterPropertiesSet(); |
| 412 | + } |
| 413 | + |
| 414 | + @Override |
| 415 | + public boolean supports(Class<?> type) { |
| 416 | + if (!super.supports(type)) { |
| 417 | + return false; |
| 418 | + } |
| 419 | + if (AnnotatedElementUtils.isAnnotated(type, Validated.class)) { |
| 420 | + return true; |
| 421 | + } |
| 422 | + if (type.getPackage().getName().startsWith("org.springframework.boot")) { |
| 423 | + return false; |
| 424 | + } |
| 425 | + if (getConstraintsForClass(type).isBeanConstrained()) { |
| 426 | + logger.warn("The @ConfigurationProperties bean " + type |
| 427 | + + " contains validation constraints but had not been annotated " |
| 428 | + + "with @Validated."); |
| 429 | + } |
| 430 | + return true; |
409 | 431 | }
|
410 | 432 |
|
411 | 433 | }
|
|
0 commit comments