Skip to content

Commit 884dfb6

Browse files
committed
Explore reduced configuration extension.
Do not register a MappingContext through the extension, instead expose a MappingContext through KeyValueAdapter so implementations can bring their own mapping context. They can also decide where to obtain the mapping context from and whether to expose it as bean at all. This is useful for a minimal configuration and removes the need to detect whether there is already a mapping context available. Detection of mapping context (or even converters) can go either into the adapter or somewhere else as detecting bean registrations depends on configuration ordering. Any later bean registrations might be not visible to our extension and so we had always the drawback of requiring any customizations being colocated within the config class that uses the Enable…Repositories annotation.
1 parent 99d0cdb commit 884dfb6

File tree

6 files changed

+35
-42
lines changed

6 files changed

+35
-42
lines changed

src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020

2121
import org.jspecify.annotations.Nullable;
2222
import org.springframework.beans.factory.DisposableBean;
23+
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
24+
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
2325
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
26+
import org.springframework.data.mapping.context.MappingContext;
2427
import org.springframework.data.util.CloseableIterator;
2528

2629
/**
@@ -32,6 +35,14 @@
3235
*/
3336
public interface KeyValueAdapter extends DisposableBean {
3437

38+
/**
39+
* Expose the {@link MappingContext} to obtain mapping metadata.
40+
*
41+
* @return the used mapping context.
42+
* @since 4.0
43+
*/
44+
MappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> getMappingContext();
45+
3546
/**
3647
* Add object with given id to keyspace.
3748
*

src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,38 +70,24 @@ public class KeyValueTemplate implements KeyValueOperations, ApplicationEventPub
7070
* @param adapter must not be {@literal null}.
7171
*/
7272
public KeyValueTemplate(KeyValueAdapter adapter) {
73-
this(adapter, new KeyValueMappingContext<>());
73+
this(adapter, DefaultIdentifierGenerator.INSTANCE);
7474
}
7575

7676
/**
77-
* Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} and {@link MappingContext}.
77+
* Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} and {@link IdentifierGenerator}.
7878
*
7979
* @param adapter must not be {@literal null}.
80-
* @param mappingContext must not be {@literal null}.
81-
*/
82-
public KeyValueTemplate(KeyValueAdapter adapter,
83-
MappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext) {
84-
this(adapter, mappingContext, DefaultIdentifierGenerator.INSTANCE);
85-
}
86-
87-
/**
88-
* Create new {@link KeyValueTemplate} using the given {@link KeyValueAdapter} and {@link MappingContext}.
89-
*
90-
* @param adapter must not be {@literal null}.
91-
* @param mappingContext must not be {@literal null}.
9280
* @param identifierGenerator must not be {@literal null}.
93-
* @since 2.4
81+
* @since 4.0
9482
*/
9583
public KeyValueTemplate(KeyValueAdapter adapter,
96-
MappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext,
9784
IdentifierGenerator identifierGenerator) {
9885

9986
Assert.notNull(adapter, "Adapter must not be null");
100-
Assert.notNull(mappingContext, "MappingContext must not be null");
10187
Assert.notNull(identifierGenerator, "IdentifierGenerator must not be null");
10288

10389
this.adapter = adapter;
104-
this.mappingContext = mappingContext;
90+
this.mappingContext = adapter.getMappingContext();
10591
this.identifierGenerator = identifierGenerator;
10692
}
10793

src/main/java/org/springframework/data/keyvalue/repository/config/KeyValueRepositoryConfigurationExtension.java

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
import java.util.Optional;
2222

2323
import org.jspecify.annotations.Nullable;
24+
2425
import org.springframework.beans.factory.support.AbstractBeanDefinition;
2526
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2627
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2728
import org.springframework.beans.factory.support.RootBeanDefinition;
2829
import org.springframework.core.annotation.AnnotationAttributes;
2930
import org.springframework.core.annotation.MergedAnnotation;
3031
import org.springframework.core.type.AnnotationMetadata;
31-
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
3232
import org.springframework.data.keyvalue.repository.KeyValueRepository;
3333
import org.springframework.data.keyvalue.repository.query.KeyValuePartTreeQuery;
3434
import org.springframework.data.keyvalue.repository.query.SpelQueryCreator;
@@ -47,7 +47,6 @@
4747
*/
4848
public abstract class KeyValueRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
4949

50-
protected static final String MAPPING_CONTEXT_BEAN_NAME = "keyValueMappingContext";
5150
protected static final String KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE = "keyValueTemplateRef";
5251

5352
@Override
@@ -78,7 +77,6 @@ public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfi
7877
builder.addPropertyReference("keyValueOperations", attributes.getString(KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE));
7978
builder.addPropertyValue("queryCreator", getQueryCreatorType(config));
8079
builder.addPropertyValue("queryType", getQueryType(config));
81-
builder.addPropertyReference("mappingContext", getMappingContextBeanRef());
8280
}
8381

8482
/**
@@ -128,15 +126,6 @@ public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConf
128126

129127
super.registerBeansForRoot(registry, configurationSource);
130128

131-
registerIfNotAlreadyRegistered(() -> {
132-
133-
RootBeanDefinition mappingContext = new RootBeanDefinition(KeyValueMappingContext.class);
134-
mappingContext.setSource(configurationSource.getSource());
135-
136-
return mappingContext;
137-
138-
}, registry, getMappingContextBeanRef(), configurationSource);
139-
140129
Optional<String> keyValueTemplateName = configurationSource.getAttribute(KEY_VALUE_TEMPLATE_BEAN_REF_ATTRIBUTE);
141130

142131
// No custom template reference configured and no matching bean definition found
@@ -174,15 +163,4 @@ public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConf
174163
*/
175164
protected abstract String getDefaultKeyValueTemplateRef();
176165

177-
/**
178-
* Returns the {@link org.springframework.data.mapping.context.MappingContext} bean name to potentially register a
179-
* default mapping context bean if no bean is registered with the returned name. Defaults to
180-
* {@link MAPPING_CONTEXT_BEAN_NAME}.
181-
*
182-
* @return the {@link org.springframework.data.mapping.context.MappingContext} bean name. Never {@literal null}.
183-
* @since 2.0
184-
*/
185-
protected String getMappingContextBeanRef() {
186-
return MAPPING_CONTEXT_BEAN_NAME;
187-
}
188166
}

src/main/java/org/springframework/data/map/MapKeyValueAdapter.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import org.springframework.data.keyvalue.core.KeyValueAdapter;
2929
import org.springframework.data.keyvalue.core.QueryEngine;
3030
import org.springframework.data.keyvalue.core.SortAccessor;
31+
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity;
32+
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
33+
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
3134
import org.springframework.data.util.CloseableIterator;
3235
import org.springframework.util.Assert;
3336
import org.springframework.util.ClassUtils;
@@ -38,12 +41,14 @@
3841
* @author Christoph Strobl
3942
* @author Derek Cochran
4043
* @author Marcel Overdijk
44+
* @author Mark Paluch
4145
*/
4246
public class MapKeyValueAdapter extends AbstractKeyValueAdapter {
4347

4448
@SuppressWarnings("rawtypes") //
4549
private final Class<? extends Map> keySpaceMapType;
4650
private final Map<String, Map<Object, Object>> store;
51+
private KeyValueMappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext = new KeyValueMappingContext<>();
4752

4853
/**
4954
* Create new {@link MapKeyValueAdapter} using {@link ConcurrentHashMap} as backing store type.
@@ -143,6 +148,16 @@ private MapKeyValueAdapter(Map<String, Map<Object, Object>> store, Class<? exten
143148
this.keySpaceMapType = keySpaceMapType;
144149
}
145150

151+
@Override
152+
public KeyValueMappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> getMappingContext() {
153+
return mappingContext;
154+
}
155+
156+
public void setMappingContext(
157+
KeyValueMappingContext<? extends KeyValuePersistentEntity<?, ?>, ? extends KeyValuePersistentProperty<?>> mappingContext) {
158+
this.mappingContext = mappingContext;
159+
}
160+
146161
@Override
147162
public @Nullable Object put(Object id, Object item, String keyspace) {
148163

src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.springframework.data.keyvalue.core.event.KeyValueEvent.BeforeGetEvent;
4848
import org.springframework.data.keyvalue.core.event.KeyValueEvent.BeforeInsertEvent;
4949
import org.springframework.data.keyvalue.core.event.KeyValueEvent.BeforeUpdateEvent;
50+
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
5051
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
5152

5253
/**
@@ -73,6 +74,7 @@ class KeyValueTemplateUnitTests {
7374

7475
@BeforeEach
7576
void setUp() {
77+
when(adapterMock.getMappingContext()).thenReturn(new KeyValueMappingContext());
7678
this.template = new KeyValueTemplate(adapterMock);
7779
this.template.setApplicationEventPublisher(publisherMock);
7880
}

src/test/java/org/springframework/data/map/repository/config/MapRepositoriesConfigurationExtensionIntegrationTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.springframework.data.keyvalue.core.QueryEngineFactory;
4545
import org.springframework.data.keyvalue.core.SortAccessor;
4646
import org.springframework.data.keyvalue.core.SpelQueryEngine;
47+
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
4748
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
4849
import org.springframework.data.keyvalue.repository.KeyValueRepository;
4950
import org.springframework.data.keyvalue.repository.query.PredicateQueryCreator;
@@ -220,7 +221,7 @@ public KeyValueOperations mapKeyValueTemplate() {
220221
public KeyValueAdapter keyValueAdapter() {
221222

222223
KeyValueAdapter mock = mock(KeyValueAdapter.class);
223-
224+
when(mock.getMappingContext()).thenReturn(new KeyValueMappingContext());
224225
when(mock.get(any(), anyString(), any())).thenThrow(new IllegalStateException("Mock"));
225226

226227
return mock;

0 commit comments

Comments
 (0)