Expose Validator bean

This commit improves ValidationAutoConfiguration so that a `Validator`
bean is exposed if JSR 303 is available. This has the side effect of
automatically enable Spring Data Couchbase's entity validation rather
than requiring to expose a `Validator` bean.

Closes gh-5178
pull/7560/merge
Stephane Nicoll 8 years ago
parent 28e86272e8
commit 9104ea81e8

@ -22,9 +22,10 @@ import com.couchbase.client.java.Bucket;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -41,7 +42,8 @@ import org.springframework.data.couchbase.repository.CouchbaseRepository;
*/
@Configuration
@ConditionalOnClass({ Bucket.class, CouchbaseRepository.class })
@AutoConfigureAfter(CouchbaseAutoConfiguration.class)
@AutoConfigureAfter({ CouchbaseAutoConfiguration.class,
ValidationAutoConfiguration.class })
@EnableConfigurationProperties(CouchbaseDataProperties.class)
@Import({ CouchbaseConfigurerAdapterConfiguration.class,
SpringBootCouchbaseDataConfiguration.class })
@ -52,7 +54,7 @@ public class CouchbaseDataAutoConfiguration {
public static class ValidationConfiguration {
@Bean
@ConditionalOnBean(Validator.class)
@ConditionalOnSingleCandidate(Validator.class)
public ValidatingCouchbaseEventListener validationEventListener(
Validator validator) {
return new ValidatingCouchbaseEventListener(validator);

@ -17,6 +17,7 @@
package org.springframework.boot.autoconfigure.validation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@ -32,6 +33,7 @@ import org.springframework.context.annotation.Conditional;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
/**
@ -42,14 +44,22 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess
* @since 1.5.0
*/
@ConditionalOnClass(ExecutableValidator.class)
@ConditionalOnResource(resources = "classpath:META-INF/services/javax.validation.spi.ValidationProvider")
@Conditional(ValidationAutoConfiguration.OnValidatorAvailableCondition.class)
public class ValidationAutoConfiguration {
@Bean
@ConditionalOnResource(resources = "classpath:META-INF/services/javax.validation.spi.ValidationProvider")
@Conditional(OnValidatorAvailableCondition.class)
@ConditionalOnMissingBean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
public Validator validator() {
return new LocalValidatorFactoryBean();
}
@Bean
@ConditionalOnMissingBean
public MethodValidationPostProcessor methodValidationPostProcessor(Validator validator) {
MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
processor.setValidator(validator);
return processor;
}
@Order(Ordered.LOWEST_PRECEDENCE)

@ -18,20 +18,17 @@ package org.springframework.boot.autoconfigure.data.couchbase;
import java.util.Set;
import javax.validation.Validator;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration;
import org.springframework.boot.autoconfigure.couchbase.CouchbaseTestConfigurer;
import org.springframework.boot.autoconfigure.data.couchbase.city.City;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.couchbase.config.AbstractCouchbaseDataConfiguration;
@ -44,7 +41,6 @@ import org.springframework.data.couchbase.repository.support.IndexManager;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link CouchbaseDataAutoConfiguration}.
@ -79,11 +75,9 @@ public class CouchbaseDataAutoConfigurationTests {
@Test
public void validatorIsPresent() {
load(ValidatorConfiguration.class);
ValidatingCouchbaseEventListener listener = this.context
.getBean(ValidatingCouchbaseEventListener.class);
assertThat(new DirectFieldAccessor(listener).getPropertyValue("validator"))
.isEqualTo(this.context.getBean(Validator.class));
load(CouchbaseTestConfigurer.class);
assertThat(this.context.getBeansOfType(ValidatingCouchbaseEventListener.class))
.hasSize(1);
}
@Test
@ -132,22 +126,12 @@ public class CouchbaseDataAutoConfigurationTests {
context.register(config);
}
context.register(PropertyPlaceholderAutoConfiguration.class,
CouchbaseAutoConfiguration.class, CouchbaseDataAutoConfiguration.class);
ValidationAutoConfiguration.class, CouchbaseAutoConfiguration.class,
CouchbaseDataAutoConfiguration.class);
context.refresh();
this.context = context;
}
@Configuration
@Import(CouchbaseTestConfigurer.class)
static class ValidatorConfiguration {
@Bean
public Validator myValidator() {
return mock(Validator.class);
}
}
@Configuration
static class CustomCouchbaseConfiguration extends AbstractCouchbaseDataConfiguration {

@ -17,6 +17,7 @@
package org.springframework.boot.autoconfigure.validation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import javax.validation.constraints.Size;
import org.junit.After;
@ -24,6 +25,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -54,6 +56,7 @@ public class ValidationAutoConfigurationTests {
@Test
public void validationIsEnabled() {
load(SampleService.class);
assertThat(this.context.getBeansOfType(Validator.class)).hasSize(1);
SampleService service = this.context.getBean(SampleService.class);
service.doSomething("Valid");
this.thrown.expect(ConstraintViolationException.class);
@ -63,10 +66,15 @@ public class ValidationAutoConfigurationTests {
@Test
public void userDefinedMethodValidationPostProcessorTakesPrecedence() {
load(SampleConfiguration.class);
assertThat(this.context.getBeansOfType(Validator.class)).hasSize(1);
Object userMethodValidationPostProcessor =
this.context.getBean("testMethodValidationPostProcessor");
assertThat(this.context.getBean(MethodValidationPostProcessor.class))
.isSameAs(this.context.getBean("testMethodValidationPostProcessor"));
.isSameAs(userMethodValidationPostProcessor);
assertThat(this.context.getBeansOfType(MethodValidationPostProcessor.class))
.hasSize(1);
assertThat(this.context.getBean(Validator.class)).isNotSameAs(
new DirectFieldAccessor(userMethodValidationPostProcessor).getPropertyValue("validator"));
}
public void load(Class<?> config) {

@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.validation;
import javax.validation.Validator;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -50,6 +52,7 @@ public class ValidationAutoConfigurationWithHibernateValidatorMissingElImplTests
public void validationIsDisabled() {
this.context = new AnnotationConfigApplicationContext(
ValidationAutoConfiguration.class);
assertThat(this.context.getBeansOfType(Validator.class)).isEmpty();
assertThat(this.context.getBeansOfType(MethodValidationPostProcessor.class))
.isEmpty();
}

@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.validation;
import javax.validation.Validator;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -49,6 +51,7 @@ public class ValidationAutoConfigurationWithoutValidatorTests {
public void validationIsDisabled() {
this.context = new AnnotationConfigApplicationContext(
ValidationAutoConfiguration.class);
assertThat(this.context.getBeansOfType(Validator.class)).isEmpty();
assertThat(this.context.getBeansOfType(MethodValidationPostProcessor.class))
.isEmpty();
}

Loading…
Cancel
Save