Merge branch '1.2.x'
This commit is contained in:
@@ -32,6 +32,7 @@ import org.springframework.context.annotation.Conditional;
|
||||
* not already contained in the {@link BeanFactory}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -53,6 +54,21 @@ public @interface ConditionalOnMissingBean {
|
||||
*/
|
||||
String[] type() default {};
|
||||
|
||||
/**
|
||||
* The class type of beans that should be ignored when identifying matching beans.
|
||||
* @return the class types of beans to ignore
|
||||
* @since 1.2.5
|
||||
*/
|
||||
Class<?>[] ignored() default {};
|
||||
|
||||
/**
|
||||
* The class type names of beans that should be ignored when identifying matching
|
||||
* beans.
|
||||
* @return the class type names of beans to ignore
|
||||
* @since 1.2.5
|
||||
*/
|
||||
String[] ignoredType() default {};
|
||||
|
||||
/**
|
||||
* The annotation type decorating a bean that should be checked. The condition matches
|
||||
* when each annotation specified is missing from all beans in the
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Dave Syer
|
||||
* @author Jakub Kubrynski
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||
class OnBeanCondition extends SpringBootCondition implements ConfigurationCondition {
|
||||
@@ -136,6 +137,10 @@ class OnBeanCondition extends SpringBootCondition implements ConfigurationCondit
|
||||
beanNames.addAll(getBeanNamesForType(beanFactory, type,
|
||||
context.getClassLoader(), considerHierarchy));
|
||||
}
|
||||
for (String ignoredType : beans.getIgnoredTypes()) {
|
||||
beanNames.removeAll(getBeanNamesForType(beanFactory, ignoredType,
|
||||
context.getClassLoader(), considerHierarchy));
|
||||
}
|
||||
for (String annotation : beans.getAnnotations()) {
|
||||
beanNames.addAll(Arrays.asList(getBeanNamesForAnnotation(beanFactory,
|
||||
annotation, context.getClassLoader(), considerHierarchy)));
|
||||
@@ -243,6 +248,8 @@ class OnBeanCondition extends SpringBootCondition implements ConfigurationCondit
|
||||
|
||||
private final List<String> annotations = new ArrayList<String>();
|
||||
|
||||
private final List<String> ignoredTypes = new ArrayList<String>();
|
||||
|
||||
private final SearchStrategy strategy;
|
||||
|
||||
public BeanSearchSpec(ConditionContext context, AnnotatedTypeMetadata metadata,
|
||||
@@ -254,6 +261,8 @@ class OnBeanCondition extends SpringBootCondition implements ConfigurationCondit
|
||||
collect(attributes, "value", this.types);
|
||||
collect(attributes, "type", this.types);
|
||||
collect(attributes, "annotation", this.annotations);
|
||||
collect(attributes, "ignored", this.ignoredTypes);
|
||||
collect(attributes, "ignoredType", this.ignoredTypes);
|
||||
if (this.types.isEmpty() && this.names.isEmpty()) {
|
||||
addDeducedBeanType(context, metadata, this.types);
|
||||
}
|
||||
@@ -350,6 +359,10 @@ class OnBeanCondition extends SpringBootCondition implements ConfigurationCondit
|
||||
return this.annotations;
|
||||
}
|
||||
|
||||
public List<String> getIgnoredTypes() {
|
||||
return this.ignoredTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder string = new StringBuilder();
|
||||
|
||||
@@ -45,7 +45,9 @@ class JacksonHttpMessageConvertersConfiguration {
|
||||
protected static class MappingJackson2HttpMessageConverterConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnMissingBean(value = MappingJackson2HttpMessageConverter.class, ignoredType = {
|
||||
"org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter",
|
||||
"org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter" })
|
||||
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(
|
||||
ObjectMapper objectMapper) {
|
||||
return new MappingJackson2HttpMessageConverter(objectMapper);
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -187,6 +188,28 @@ public class ConditionalOnMissingBeanTests {
|
||||
equalTo("fromFactory"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithIgnoredSubclass() {
|
||||
this.context.register(CustomExampleBeanConfiguration.class,
|
||||
ConditionalOnIgnoredSubclass.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBeansOfType(ExampleBean.class).size(), is(equalTo(2)));
|
||||
assertThat(this.context.getBeansOfType(CustomExampleBean.class).size(),
|
||||
is(equalTo(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithIgnoredSubclassByName() {
|
||||
this.context.register(CustomExampleBeanConfiguration.class,
|
||||
ConditionalOnIgnoredSubclassByName.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBeansOfType(ExampleBean.class).size(), is(equalTo(2)));
|
||||
assertThat(this.context.getBeansOfType(CustomExampleBean.class).size(),
|
||||
is(equalTo(1)));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(name = "foo")
|
||||
protected static class OnBeanNameConfiguration {
|
||||
@@ -299,6 +322,38 @@ public class ConditionalOnMissingBeanTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ConditionalOnIgnoredSubclass {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ExampleBean.class, ignored = CustomExampleBean.class)
|
||||
public ExampleBean exampleBean() {
|
||||
return new ExampleBean("test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ConditionalOnIgnoredSubclassByName {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ExampleBean.class, ignoredType = "org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBeanTests.CustomExampleBean")
|
||||
public ExampleBean exampleBean() {
|
||||
return new ExampleBean("test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class CustomExampleBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public CustomExampleBean customExampleBean() {
|
||||
return new CustomExampleBean();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(annotation = EnableScheduling.class)
|
||||
protected static class OnAnnotationConfiguration {
|
||||
@@ -369,6 +424,14 @@ public class ConditionalOnMissingBeanTests {
|
||||
|
||||
}
|
||||
|
||||
public static class CustomExampleBean extends ExampleBean {
|
||||
|
||||
public CustomExampleBean() {
|
||||
super("custom subclass");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ExampleFactoryBean implements FactoryBean<ExampleBean> {
|
||||
|
||||
public ExampleFactoryBean(String value) {
|
||||
|
||||
@@ -18,15 +18,21 @@ package org.springframework.boot.autoconfigure.web;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.GsonHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
@@ -36,7 +42,10 @@ import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConve
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
@@ -187,6 +196,39 @@ public class HttpMessageConvertersAutoConfigurationTests {
|
||||
assertConverterBeanRegisteredWithHttpMessageConverters(StringHttpMessageConverter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeConstrainedConverterDoesNotPreventAutoConfigurationOfJacksonConverter()
|
||||
throws Exception {
|
||||
this.context.register(JacksonObjectMapperBuilderConfig.class,
|
||||
TypeConstrainedConverterConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
BeanDefinition beanDefinition = this.context
|
||||
.getBeanDefinition("mappingJackson2HttpMessageConverter");
|
||||
assertThat(beanDefinition.getFactoryBeanName(),
|
||||
is(equalTo(MappingJackson2HttpMessageConverterConfiguration.class
|
||||
.getName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeConstrainedConverterFromSpringDataDoesNotPreventAutoConfigurationOfJacksonConverter()
|
||||
throws Exception {
|
||||
this.context.register(JacksonObjectMapperBuilderConfig.class,
|
||||
RepositoryRestMvcConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
Map<String, MappingJackson2HttpMessageConverter> beansOfType = this.context
|
||||
.getBeansOfType(MappingJackson2HttpMessageConverter.class);
|
||||
System.out.println(beansOfType);
|
||||
BeanDefinition beanDefinition = this.context
|
||||
.getBeanDefinition("mappingJackson2HttpMessageConverter");
|
||||
assertThat(beanDefinition.getFactoryBeanName(),
|
||||
is(equalTo(MappingJackson2HttpMessageConverterConfiguration.class
|
||||
.getName())));
|
||||
}
|
||||
|
||||
private void assertConverterBeanExists(Class<?> type, String beanName) {
|
||||
assertEquals(1, this.context.getBeansOfType(type).size());
|
||||
List<String> beanNames = Arrays.asList(this.context.getBeanDefinitionNames());
|
||||
@@ -254,4 +296,14 @@ public class HttpMessageConvertersAutoConfigurationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TypeConstrainedConverterConfiguration {
|
||||
|
||||
@Bean
|
||||
public TypeConstrainedMappingJackson2HttpMessageConverter typeConstrainedConverter() {
|
||||
return new TypeConstrainedMappingJackson2HttpMessageConverter(
|
||||
ResourceSupport.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user