diff options
author | Emmanuel Bourg <ebourg@apache.org> | 2017-07-04 11:41:53 +0200 |
---|---|---|
committer | Emmanuel Bourg <ebourg@apache.org> | 2017-07-04 11:41:53 +0200 |
commit | 16cac1f52d8e8159e0e688b2fda3f89291cec969 (patch) | |
tree | 027fd3c0b671bf73a45f27af2a16881c4098f7e7 /spring-context | |
parent | 5b251f9ca7596793d669a9a36eb0d83ccd56f983 (diff) |
New upstream version 4.3.9
Diffstat (limited to 'spring-context')
10 files changed, 194 insertions, 52 deletions
diff --git a/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java b/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java index 2a029280..1f6ecc41 100644 --- a/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -103,18 +103,19 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life void setParent(ApplicationContext parent); /** - * Return the Environment for this application context in configurable form. + * Set the {@code Environment} for this application context. + * @param environment the new environment * @since 3.1 */ - @Override - ConfigurableEnvironment getEnvironment(); + void setEnvironment(ConfigurableEnvironment environment); /** - * Set the {@code Environment} for this application context. - * @param environment the new environment + * Return the {@code Environment} for this application context in configurable + * form, allowing for further customization. * @since 3.1 */ - void setEnvironment(ConfigurableEnvironment environment); + @Override + ConfigurableEnvironment getEnvironment(); /** * Add a new BeanFactoryPostProcessor that will get applied to the internal diff --git a/spring-context/src/main/java/org/springframework/context/EnvironmentAware.java b/spring-context/src/main/java/org/springframework/context/EnvironmentAware.java index 0d943429..7a7640ed 100644 --- a/spring-context/src/main/java/org/springframework/context/EnvironmentAware.java +++ b/spring-context/src/main/java/org/springframework/context/EnvironmentAware.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,11 +25,12 @@ import org.springframework.core.env.Environment; * * @author Chris Beams * @since 3.1 + * @see org.springframework.core.env.EnvironmentCapable */ public interface EnvironmentAware extends Aware { /** - * Set the {@code Environment} that this object runs in. + * Set the {@code Environment} that this component runs in. */ void setEnvironment(Environment environment); diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index cabf3800..6791f436 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -281,8 +281,22 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader } /** - * {@inheritDoc} - * <p>If {@code null}, a new environment will be initialized via + * Set the {@code Environment} for this application context. + * <p>Default value is determined by {@link #createEnvironment()}. Replacing the + * default with this method is one option but configuration through {@link + * #getEnvironment()} should also be considered. In either case, such modifications + * should be performed <em>before</em> {@link #refresh()}. + * @see org.springframework.context.support.AbstractApplicationContext#createEnvironment + */ + @Override + public void setEnvironment(ConfigurableEnvironment environment) { + this.environment = environment; + } + + /** + * Return the {@code Environment} for this application context in configurable + * form, allowing for further customization. + * <p>If none specified, a default environment will be initialized via * {@link #createEnvironment()}. */ @Override @@ -294,16 +308,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader } /** - * {@inheritDoc} - * <p>Default value is determined by {@link #createEnvironment()}. Replacing the - * default with this method is one option but configuration through {@link - * #getEnvironment()} should also be considered. In either case, such modifications - * should be performed <em>before</em> {@link #refresh()}. - * @see org.springframework.context.support.AbstractApplicationContext#createEnvironment + * Create and return a new {@link StandardEnvironment}. + * <p>Subclasses may override this method in order to supply + * a custom {@link ConfigurableEnvironment} implementation. */ - @Override - public void setEnvironment(ConfigurableEnvironment environment) { - this.environment = environment; + protected ConfigurableEnvironment createEnvironment() { + return new StandardEnvironment(); } /** @@ -444,7 +454,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader //--------------------------------------------------------------------- /** - * {@inheritDoc} + * Set the parent of this application context. * <p>The parent {@linkplain ApplicationContext#getEnvironment() environment} is * {@linkplain ConfigurableEnvironment#merge(ConfigurableEnvironment) merged} with * this (child) application context environment if the parent is non-{@code null} and @@ -495,15 +505,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader return this.applicationListeners; } - /** - * Create and return a new {@link StandardEnvironment}. - * <p>Subclasses may override this method in order to supply - * a custom {@link ConfigurableEnvironment} implementation. - */ - protected ConfigurableEnvironment createEnvironment() { - return new StandardEnvironment(); - } - @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { @@ -935,13 +936,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader /** * DisposableBean callback for destruction of this instance. - * Only called when the ApplicationContext itself is running - * as a bean in another BeanFactory or ApplicationContext, - * which is rather unusual. - * <p>The {@code close} method is the native way to - * shut down an ApplicationContext. + * <p>The {@link #close()} method is the native way to shut down + * an ApplicationContext, which this method simply delegates to. * @see #close() - * @see org.springframework.beans.factory.access.SingletonBeanFactoryLocator */ @Override public void destroy() { diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index fcf17665..77de2543 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -221,6 +221,7 @@ public class ScheduledAnnotationBeanPostProcessor this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, false)); } catch (NoUniqueBeanDefinitionException ex) { + logger.debug("Could not find unique TaskScheduler bean", ex); try { this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, true)); } @@ -241,6 +242,7 @@ public class ScheduledAnnotationBeanPostProcessor this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, false)); } catch (NoUniqueBeanDefinitionException ex2) { + logger.debug("Could not find unique ScheduledExecutorService bean", ex2); try { this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, true)); } diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java index 33d53bf9..97006cf4 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import javax.validation.ConstraintValidatorFactory; import javax.validation.MessageInterpolator; import javax.validation.TraversableResolver; import javax.validation.Validation; +import javax.validation.ValidationException; import javax.validation.ValidationProviderResolver; import javax.validation.Validator; import javax.validation.ValidatorContext; @@ -74,6 +75,7 @@ import org.springframework.util.ReflectionUtils; * instead. If you really need programmatic {@code #forExecutables} access, inject this class as * a {@link ValidatorFactory} and call {@link #getValidator()} on it, then {@code #forExecutables} * on the returned native {@link Validator} reference instead of directly on this class. + * Alternatively, call {@code #unwrap(Validator.class) which will also provide the native object. * * <p>This class is also being used by Spring's MVC configuration namespace, in case of the * {@code javax.validation} API being present but no explicit Validator having been configured. @@ -397,6 +399,30 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter return this.validatorFactory.getConstraintValidatorFactory(); } + @Override + @SuppressWarnings("unchecked") + public <T> T unwrap(Class<T> type) { + if (type == null || !ValidatorFactory.class.isAssignableFrom(type)) { + try { + return super.unwrap(type); + } + catch (ValidationException ex) { + // ignore - we'll try ValidatorFactory unwrapping next + } + } + try { + return this.validatorFactory.unwrap(type); + } + catch (ValidationException ex) { + // ignore if just being asked for ValidatorFactory + if (ValidatorFactory.class == type) { + return (T) this.validatorFactory; + } + throw ex; + } + } + + public void close() { if (closeMethod != null && this.validatorFactory != null) { ReflectionUtils.invokeMethod(closeMethod, this.validatorFactory); diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java index a2972a13..e1d4eff5 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java @@ -85,9 +85,13 @@ public class MethodValidationPostProcessor extends AbstractBeanFactoryAwareAdvis * <p>Default is the default ValidatorFactory's default Validator. */ public void setValidator(Validator validator) { + // Unwrap to the native Validator with forExecutables support if (validator instanceof LocalValidatorFactoryBean) { this.validator = ((LocalValidatorFactoryBean) validator).getValidator(); } + else if (validator instanceof SpringValidatorAdapter) { + this.validator = validator.unwrap(Validator.class); + } else { this.validator = validator; } diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java index a2a2125a..3614dfe0 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java @@ -25,6 +25,8 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; import javax.validation.ConstraintViolation; +import javax.validation.ValidationException; +import javax.validation.Validator; import javax.validation.metadata.BeanDescriptor; import javax.validation.metadata.ConstraintDescriptor; @@ -39,13 +41,19 @@ import org.springframework.validation.ObjectError; import org.springframework.validation.SmartValidator; /** - * Adapter that takes a JSR-303 {@code javax.validator.Validator} - * and exposes it as a Spring {@link org.springframework.validation.Validator} + * Adapter that takes a JSR-303 {@code javax.validator.Validator} and + * exposes it as a Spring {@link org.springframework.validation.Validator} * while also exposing the original JSR-303 Validator interface itself. * * <p>Can be used as a programmatic wrapper. Also serves as base class for * {@link CustomValidatorBean} and {@link LocalValidatorFactoryBean}. * + * <p>Note that Bean Validation 1.1's {@code #forExecutables} method isn't supported + * on this adapter: We do not expect that method to be called by application code; + * consider {@link MethodValidationInterceptor} instead. If you really need programmatic + * {@code #forExecutables} access, call {@code #unwrap(Validator.class) which will + * provide the native {@link Validator} object with {@code #forExecutables} support. + * * @author Juergen Hoeller * @since 3.0 */ @@ -297,7 +305,16 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation. @SuppressWarnings("unchecked") public <T> T unwrap(Class<T> type) { Assert.state(this.targetValidator != null, "No target Validator set"); - return (type != null ? this.targetValidator.unwrap(type) : (T) this.targetValidator); + try { + return (type != null ? this.targetValidator.unwrap(type) : (T) this.targetValidator); + } + catch (ValidationException ex) { + // ignore if just being asked for plain Validator + if (javax.validation.Validator.class == type) { + return (T) this.targetValidator; + } + throw ex; + } } diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java index 3e5cf952..e1106af7 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java @@ -23,6 +23,7 @@ import java.lang.annotation.Target; import java.lang.reflect.Method; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; +import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.junit.Ignore; @@ -43,6 +44,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.core.Ordered; +import org.springframework.scheduling.concurrent.CustomizableThreadFactory; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import org.springframework.util.ReflectionUtils; @@ -181,9 +183,23 @@ public class EnableAsyncTests { } @Test - public void customExecutorIsPropagated() throws InterruptedException { + public void customExecutorBean() throws InterruptedException { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); - ctx.register(CustomExecutorAsyncConfig.class); + ctx.register(CustomExecutorBean.class); + ctx.refresh(); + + AsyncBean asyncBean = ctx.getBean(AsyncBean.class); + asyncBean.work(); + Thread.sleep(500); + assertThat(asyncBean.getThreadOfExecution().getName(), startsWith("Custom-")); + + ctx.close(); + } + + @Test + public void customExecutorConfig() throws InterruptedException { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(CustomExecutorConfig.class); ctx.refresh(); AsyncBean asyncBean = ctx.getBean(AsyncBean.class); @@ -382,7 +398,23 @@ public class EnableAsyncTests { @Configuration @EnableAsync - static class CustomExecutorAsyncConfig implements AsyncConfigurer { + static class CustomExecutorBean { + + @Bean + public AsyncBean asyncBean() { + return new AsyncBean(); + } + + @Bean + public Executor taskExecutor() { + return Executors.newSingleThreadExecutor(new CustomizableThreadFactory("Custom-")); + } + } + + + @Configuration + @EnableAsync + static class CustomExecutorConfig implements AsyncConfigurer { @Bean public AsyncBean asyncBean() { diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java index de7bc833..307acc59 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/SpringValidatorAdapterTests.java @@ -27,6 +27,7 @@ import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import javax.validation.Payload; import javax.validation.Validation; +import javax.validation.Validator; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; @@ -51,8 +52,9 @@ import static org.junit.Assert.*; */ public class SpringValidatorAdapterTests { - private final SpringValidatorAdapter validatorAdapter = new SpringValidatorAdapter( - Validation.buildDefaultValidatorFactory().getValidator()); + private final Validator nativeValidator = Validation.buildDefaultValidatorFactory().getValidator(); + + private final SpringValidatorAdapter validatorAdapter = new SpringValidatorAdapter(nativeValidator); private final StaticMessageSource messageSource = new StaticMessageSource(); @@ -66,6 +68,12 @@ public class SpringValidatorAdapterTests { } + @Test + public void testUnwrap() { + Validator nativeValidator = validatorAdapter.unwrap(Validator.class); + assertSame(this.nativeValidator, nativeValidator); + } + @Test // SPR-13406 public void testNoStringArgumentValue() { TestBean testBean = new TestBean(); diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java index 26138af5..d5a4fb79 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,11 +33,18 @@ import javax.validation.ConstraintValidatorContext; import javax.validation.ConstraintViolation; import javax.validation.Payload; import javax.validation.Valid; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; import javax.validation.constraints.NotNull; import org.hibernate.validator.HibernateValidator; +import org.hibernate.validator.HibernateValidatorFactory; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.core.env.Environment; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.Errors; import org.springframework.validation.FieldError; @@ -47,10 +54,9 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; /** - * Tested against Hibernate Validator 4.3, as of Spring 4.0. + * Tests against Hibernate Validator 5.x. * * @author Juergen Hoeller - * @since 3.0 */ public class ValidatorFactoryTests { @@ -58,6 +64,7 @@ public class ValidatorFactoryTests { public void testSimpleValidation() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); Set<ConstraintViolation<ValidPerson>> result = validator.validate(person); assertEquals(2, result.size()); @@ -70,6 +77,12 @@ public class ValidatorFactoryTests { fail("Invalid constraint violation with path '" + path + "'"); } } + + Validator nativeValidator = validator.unwrap(Validator.class); + assertTrue(nativeValidator.getClass().getName().startsWith("org.hibernate")); + assertTrue(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory); + assertTrue(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory); + validator.destroy(); } @@ -78,6 +91,7 @@ public class ValidatorFactoryTests { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setProviderClass(HibernateValidator.class); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); Set<ConstraintViolation<ValidPerson>> result = validator.validate(person); assertEquals(2, result.size()); @@ -90,6 +104,12 @@ public class ValidatorFactoryTests { fail("Invalid constraint violation with path '" + path + "'"); } } + + Validator nativeValidator = validator.unwrap(Validator.class); + assertTrue(nativeValidator.getClass().getName().startsWith("org.hibernate")); + assertTrue(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory); + assertTrue(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory); + validator.destroy(); } @@ -112,6 +132,7 @@ public class ValidatorFactoryTests { public void testSpringValidationFieldType() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.setName("Phil"); person.getAddress().setStreet("Phil's Street"); @@ -126,6 +147,7 @@ public class ValidatorFactoryTests { public void testSpringValidation() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); validator.validate(person, result); @@ -153,6 +175,7 @@ public class ValidatorFactoryTests { public void testSpringValidationWithClassLevel() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.setName("Juergen"); person.getAddress().setStreet("Juergen's Street"); @@ -167,9 +190,31 @@ public class ValidatorFactoryTests { } @Test + public void testSpringValidationWithAutowiredValidator() throws Exception { + ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext( + LocalValidatorFactoryBean.class); + LocalValidatorFactoryBean validator = ctx.getBean(LocalValidatorFactoryBean.class); + + ValidPerson person = new ValidPerson(); + person.expectsAutowiredValidator = true; + person.setName("Juergen"); + person.getAddress().setStreet("Juergen's Street"); + BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); + validator.validate(person, result); + assertEquals(1, result.getErrorCount()); + ObjectError globalError = result.getGlobalError(); + List<String> errorCodes = Arrays.asList(globalError.getCodes()); + assertEquals(2, errorCodes.size()); + assertTrue(errorCodes.contains("NameAddressValid.person")); + assertTrue(errorCodes.contains("NameAddressValid")); + ctx.close(); + } + + @Test public void testSpringValidationWithErrorInListElement() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.getAddressList().add(new ValidAddress()); BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); @@ -187,6 +232,7 @@ public class ValidatorFactoryTests { public void testSpringValidationWithErrorInSetElement() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); person.getAddressSet().add(new ValidAddress()); BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); @@ -235,10 +281,12 @@ public class ValidatorFactoryTests { private ValidAddress address = new ValidAddress(); @Valid - private List<ValidAddress> addressList = new LinkedList<ValidAddress>(); + private List<ValidAddress> addressList = new LinkedList<>(); @Valid - private Set<ValidAddress> addressSet = new LinkedHashSet<ValidAddress>(); + private Set<ValidAddress> addressSet = new LinkedHashSet<>(); + + public boolean expectsAutowiredValidator = false; public String getName() { return name; @@ -304,12 +352,18 @@ public class ValidatorFactoryTests { public static class NameAddressValidator implements ConstraintValidator<NameAddressValid, ValidPerson> { + @Autowired + private Environment environment; + @Override public void initialize(NameAddressValid constraintAnnotation) { } @Override public boolean isValid(ValidPerson value, ConstraintValidatorContext context) { + if (value.expectsAutowiredValidator) { + assertNotNull(this.environment); + } boolean valid = (value.name == null || !value.address.street.contains(value.name)); if (!valid && "Phil".equals(value.name)) { context.buildConstraintViolationWithTemplate( @@ -378,7 +432,7 @@ public class ValidatorFactoryTests { public boolean isValid(InnerBean bean, ConstraintValidatorContext context) { context.disableDefaultConstraintViolation(); if (bean.getValue() == null) { - context.buildConstraintViolationWithTemplate("NULL"). addNode("value").addConstraintViolation(); + context.buildConstraintViolationWithTemplate("NULL").addNode("value").addConstraintViolation(); return false; } return true; |