GH-1484 common strategy for extended binding properties

Resolves #1484
This commit is contained in:
Oleg Zhurakousky
2018-09-19 10:41:32 +02:00
parent c8e9306bc8
commit 1f3b6ed344
5 changed files with 55 additions and 31 deletions

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2018 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder;
/**
*
* @author Oleg Zhurakousky
*
* @since 2.1
*
*/
public interface BinderSpecificPropertiesProvider {
Object getConsumer();
Object getProducer();
}

View File

@@ -35,7 +35,7 @@ import org.springframework.cloud.stream.config.MergableProperties;
* @author Oleg Zhurakousky
*/
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class ConsumerProperties implements MergableProperties{
public class ConsumerProperties implements MergableProperties {
/**
* The concurrency setting of the consumer. Default: 1.

View File

@@ -47,13 +47,12 @@ public interface ExtendedBindingProperties<C, P> {
/**
*
* Extended properties class against which default extended producer and consumer properties
* are resolved. It is expected that this class has two properties - one called producer
* and another called consumer that contains the extended properties for producer and
* consumer respectively.
* Extended properties class which should be a subclass of {@link BinderSpecificPropertiesProvider}
* against which default extended producer and consumer properties
* are resolved.
*
* @return extended properties class that contains extended producer/consumer properties
* @since 2.1.0
*/
Class<?> getExtendedPropertiesEntryClass();
Class<? extends BinderSpecificPropertiesProvider> getExtendedPropertiesEntryClass();
}

View File

@@ -16,7 +16,6 @@
package org.springframework.cloud.stream.binding;
import java.lang.reflect.Field;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Collection;
@@ -35,6 +34,7 @@ import org.springframework.boot.context.properties.bind.PropertySourcesPlacehold
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.cloud.stream.binder.Binder;
import org.springframework.cloud.stream.binder.BinderFactory;
import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider;
import org.springframework.cloud.stream.binder.Binding;
import org.springframework.cloud.stream.binder.ConsumerProperties;
import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
@@ -51,7 +51,6 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.integration.support.utils.IntegrationUtils;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.DataBinder;
import org.springframework.validation.beanvalidation.CustomValidatorBean;
@@ -122,7 +121,7 @@ public class BindingService implements ApplicationContextAware {
if (MergableProperties.class.isAssignableFrom(extendedConsumerProperties.getExtension().getClass())) {
handleExtendedDefaultProperties((ExtendedPropertiesBinder) binder,
(MergableProperties) extendedConsumerProperties.getExtension(), "consumer");
(MergableProperties) extendedConsumerProperties.getExtension(), false);
}
consumerProperties = extendedConsumerProperties;
@@ -247,7 +246,7 @@ public class BindingService implements ApplicationContextAware {
if (MergableProperties.class.isAssignableFrom(extendedProducerProperties.getExtension().getClass())) {
handleExtendedDefaultProperties((ExtendedPropertiesBinder) binder,
(MergableProperties) extendedProducerProperties.getExtension(), "producer");
(MergableProperties) extendedProducerProperties.getExtension(), true);
}
producerProperties = extendedProducerProperties;
}
@@ -257,26 +256,21 @@ public class BindingService implements ApplicationContextAware {
return binding;
}
private void handleExtendedDefaultProperties(ExtendedPropertiesBinder<?,?,?> binder, MergableProperties extendedProperties, String filedName) {
private void handleExtendedDefaultProperties(ExtendedPropertiesBinder<?,?,?> binder, MergableProperties extendedProperties, boolean producer) {
String defaultsPrefix = binder.getDefaultsPrefix();
Class<?> extendedPropertiesEntryClass = binder.getExtendedPropertiesEntryClass();
if (defaultsPrefix != null && extendedPropertiesEntryClass != null) {
if (defaultsPrefix != null) {
Class<? extends BinderSpecificPropertiesProvider> extendedPropertiesEntryClass = binder.getExtendedPropertiesEntryClass();
if (BinderSpecificPropertiesProvider.class.isAssignableFrom(extendedPropertiesEntryClass)) {
org.springframework.boot.context.properties.bind.Binder extendedPropertiesResolverBinder =
new org.springframework.boot.context.properties.bind.Binder(ConfigurationPropertySources.get(applicationContext.getEnvironment()),
new PropertySourcesPlaceholdersResolver(applicationContext.getEnvironment()),
IntegrationUtils.getConversionService(this.applicationContext.getBeanFactory()), null);
BinderSpecificPropertiesProvider defaultProperties = BeanUtils.instantiateClass(extendedPropertiesEntryClass);
extendedPropertiesResolverBinder.bind(defaultsPrefix, Bindable.ofInstance(defaultProperties));
org.springframework.boot.context.properties.bind.Binder extendedPropertiesResolverBinder =
new org.springframework.boot.context.properties.bind.Binder(ConfigurationPropertySources.get(applicationContext.getEnvironment()),
new PropertySourcesPlaceholdersResolver(applicationContext.getEnvironment()),
IntegrationUtils.getConversionService(this.applicationContext.getBeanFactory()), null);
Object defaultProperties = BeanUtils.instantiateClass(extendedPropertiesEntryClass);
extendedPropertiesResolverBinder.bind(defaultsPrefix, Bindable.ofInstance(defaultProperties));
Field extendedPropertyField = ReflectionUtils.findField(defaultProperties.getClass(), filedName);
if (extendedPropertyField != null) {
extendedPropertyField.setAccessible(true);
Object extendedProducerObject = ReflectionUtils.getField(extendedPropertyField, defaultProperties);
if (extendedProducerObject != null) {
((MergableProperties)extendedProducerObject).merge(extendedProperties);
}
Object binderExtendedProperties = producer ? defaultProperties.getProducer() : defaultProperties.getConsumer();
((MergableProperties)binderExtendedProperties).merge(extendedProperties);
}
}
}
@@ -287,9 +281,7 @@ public class BindingService implements ApplicationContextAware {
if (binder instanceof ExtendedPropertiesBinder) {
return ((ExtendedPropertiesBinder) binder).getExtendedProducerProperties(outputName);
}
else {
return null;
}
return null;
}
public <T> Binding<T> doBindProducer(T output, String bindingTarget, Binder<T, ?, ProducerProperties> binder,

View File

@@ -16,10 +16,12 @@
package org.springframework.cloud.stream.utils;
import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider;
/**
* @author Soby Chacko
*/
public class FooBindingProperties {
public class FooBindingProperties implements BinderSpecificPropertiesProvider {
private FooExtendedProducerProperties producer = new FooExtendedProducerProperties();