DATAKV-87 - Allow definition of target Map type via @EnableMapRepositories.
We added the configuration attribute ‘mapType’ to @EnableMapRepositories which allows to change defaulting of the Map structure used by the MapKeyValueAdapter. To do so we now register a MapKeyValueAdapterFactory and delegate creation of the adapter to it. This also allows usage of interface types such as plain java.util.Map which will initialize the adapter with the approximated type resolved via CollectionFactory. Original pull request #2.
This commit is contained in:
committed by
Oliver Gierke
parent
5a14d7bc12
commit
b16a454c6c
@@ -21,6 +21,8 @@ import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
@@ -121,4 +123,11 @@ public @interface EnableMapRepositories {
|
||||
* repositories infrastructure.
|
||||
*/
|
||||
boolean considerNestedRepositories() default false;
|
||||
|
||||
/**
|
||||
* Configures the {@link Map} structure used for data storage. Defaults to {@link ConcurrentHashMap}. Will be ignored
|
||||
* in favor of existing {@link KeyValueOperations} definition.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
Class<? extends Map> mapType() default ConcurrentHashMap.class;
|
||||
}
|
||||
|
||||
@@ -15,11 +15,20 @@
|
||||
*/
|
||||
package org.springframework.data.map.repository.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.data.keyvalue.core.KeyValueTemplate;
|
||||
import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension;
|
||||
import org.springframework.data.map.MapKeyValueAdapter;
|
||||
import org.springframework.data.map.MapKeyValueAdapterFactory;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationSource;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
@@ -58,14 +67,43 @@ public class MapRepositoryConfigurationExtension extends KeyValueRepositoryConfi
|
||||
* @see org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension#getDefaultKeyValueTemplateBeanDefinition()
|
||||
*/
|
||||
@Override
|
||||
protected RootBeanDefinition getDefaultKeyValueTemplateBeanDefinition() {
|
||||
|
||||
RootBeanDefinition keyValueTemplateDefinition = new RootBeanDefinition(KeyValueTemplate.class);
|
||||
protected RootBeanDefinition getDefaultKeyValueTemplateBeanDefinition(
|
||||
RepositoryConfigurationSource configurationSource) {
|
||||
|
||||
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
|
||||
constructorArgumentValues.addGenericArgumentValue(new RootBeanDefinition(MapKeyValueAdapter.class));
|
||||
|
||||
GenericBeanDefinition referencingMapKeyValueAdapterBeanDefintion = new GenericBeanDefinition();
|
||||
referencingMapKeyValueAdapterBeanDefintion.setBeanClass(MapKeyValueAdapter.class);
|
||||
referencingMapKeyValueAdapterBeanDefintion.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
|
||||
|
||||
constructorArgumentValues.addGenericArgumentValue(referencingMapKeyValueAdapterBeanDefintion);
|
||||
|
||||
RootBeanDefinition keyValueTemplateDefinition = new RootBeanDefinition(KeyValueTemplate.class);
|
||||
keyValueTemplateDefinition.setConstructorArgumentValues(constructorArgumentValues);
|
||||
keyValueTemplateDefinition.setRole(BeanDefinition.ROLE_APPLICATION);
|
||||
|
||||
return keyValueTemplateDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
protected void registerTemplateInfrastructure(BeanDefinitionRegistry registry,
|
||||
RepositoryConfigurationSource configurationSource) {
|
||||
|
||||
Class<? extends Map> type = (Class<? extends Map>) ((AnnotationMetadata) configurationSource.getSource())
|
||||
.getAnnotationAttributes(EnableMapRepositories.class.getName()).get("mapType");
|
||||
|
||||
ConstructorArgumentValues mapAdapterFactoryArgs = new ConstructorArgumentValues();
|
||||
mapAdapterFactoryArgs.addGenericArgumentValue(type);
|
||||
RootBeanDefinition mapAdapterFactory = new RootBeanDefinition(MapKeyValueAdapterFactory.class,
|
||||
mapAdapterFactoryArgs, null);
|
||||
|
||||
registry.registerBeanDefinition("mapKeyValueAdapterFactory", mapAdapterFactory);
|
||||
|
||||
RootBeanDefinition mapKeyValueAdapter = new RootBeanDefinition(MapKeyValueAdapter.class);
|
||||
mapKeyValueAdapter.setFactoryBeanName("mapKeyValueAdapterFactory");
|
||||
mapKeyValueAdapter.setFactoryMethodName("getAdapter");
|
||||
|
||||
registry.registerBeanDefinition("mapKeyValueAdapter", mapAdapterFactory);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user