Browse Source

Resolve `@ReadPreference` on actual repository interface.

Original pull request: #4545
Closes #4542
pull/4547/head
Christoph Strobl 2 years ago committed by Mark Paluch
parent
commit
e78e1978d5
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 14
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java
  2. 59
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/DefaultCrudMethodMetadataUnitTests.java
  3. 6
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryUnitTests.java

14
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/CrudMethodMetadataPostProcessor.java

@ -89,9 +89,12 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B @@ -89,9 +89,12 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B
private final ConcurrentMap<Method, CrudMethodMetadata> metadataCache = new ConcurrentHashMap<>();
private final Set<Method> implementations = new HashSet<>();
private final RepositoryInformation repositoryInformation;
CrudMethodMetadataPopulatingMethodInterceptor(RepositoryInformation repositoryInformation) {
this.repositoryInformation = repositoryInformation;
ReflectionUtils.doWithMethods(repositoryInformation.getRepositoryInterface(), implementations::add,
method -> !repositoryInformation.isQueryMethod(method));
}
@ -140,7 +143,7 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B @@ -140,7 +143,7 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B
if (methodMetadata == null) {
methodMetadata = new DefaultCrudMethodMetadata(method);
methodMetadata = new DefaultCrudMethodMetadata(repositoryInformation.getRepositoryInterface(), method);
CrudMethodMetadata tmp = metadataCache.putIfAbsent(method, methodMetadata);
if (tmp != null) {
@ -171,23 +174,24 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B @@ -171,23 +174,24 @@ class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, B
/**
* Creates a new {@link DefaultCrudMethodMetadata} for the given {@link Method}.
*
* @param repositoryInterface the target repository interface.
* @param method must not be {@literal null}.
*/
DefaultCrudMethodMetadata(Method method) {
DefaultCrudMethodMetadata(Class<?> repositoryInterface, Method method) {
Assert.notNull(method, "Method must not be null");
this.readPreference = findReadPreference(method);
this.readPreference = findReadPreference(repositoryInterface, method);
}
private Optional<ReadPreference> findReadPreference(Method method) {
private Optional<ReadPreference> findReadPreference(Class<?> repositoryInterface, Method method) {
org.springframework.data.mongodb.repository.ReadPreference preference = AnnotatedElementUtils
.findMergedAnnotation(method, org.springframework.data.mongodb.repository.ReadPreference.class);
if (preference == null) {
preference = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(),
preference = AnnotatedElementUtils.findMergedAnnotation(repositoryInterface,
org.springframework.data.mongodb.repository.ReadPreference.class);
}

59
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/DefaultCrudMethodMetadataUnitTests.java

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
/*
* Copyright 2023 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
*
* https://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.data.mongodb.repository.support;
import static org.assertj.core.api.Assertions.*;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.data.mongodb.repository.Person;
import org.springframework.data.mongodb.repository.ReadPreference;
import org.springframework.data.mongodb.repository.support.CrudMethodMetadataPostProcessor.DefaultCrudMethodMetadata;
import org.springframework.data.repository.CrudRepository;
import org.springframework.util.ReflectionUtils;
/**
* @author Christoph Strobl
*/
class DefaultCrudMethodMetadataUnitTests {
@Test // GH-4542
void detectsReadPreferenceOnRepositoryInterface() {
DefaultCrudMethodMetadata metadata = new DefaultCrudMethodMetadata(ReadPreferenceAnnotated.class,
ReflectionUtils.findMethod(ReadPreferenceAnnotated.class, "findAll"));
assertThat(metadata.getReadPreference()).hasValue(com.mongodb.ReadPreference.primary());
}
@Test // GH-4542
void favorsReadPreferenceOfAnnotatedMethod() {
DefaultCrudMethodMetadata metadata = new DefaultCrudMethodMetadata(ReadPreferenceAnnotated.class,
ReflectionUtils.findMethod(ReadPreferenceAnnotated.class, "findById", Object.class));
assertThat(metadata.getReadPreference()).hasValue(com.mongodb.ReadPreference.secondary());
}
@ReadPreference("primary")
interface ReadPreferenceAnnotated extends CrudRepository<Person, String> {
@Override
@ReadPreference("secondary")
Optional<Person> findById(String s);
}
}

6
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepositoryUnitTests.java

@ -152,7 +152,7 @@ public class SimpleMongoRepositoryUnitTests { @@ -152,7 +152,7 @@ public class SimpleMongoRepositoryUnitTests {
repository = new SimpleMongoRepository<>(entityInformation, mongoOperations);
repository.setRepositoryMethodMetadata(
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class.getMethod("dummy")));
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class, TestRepositoryWithReadPreference.class.getMethod("dummy")));
findCall.accept(repository);
@ -167,7 +167,7 @@ public class SimpleMongoRepositoryUnitTests { @@ -167,7 +167,7 @@ public class SimpleMongoRepositoryUnitTests {
repository = new SimpleMongoRepository<>(entityInformation, mongoOperations);
repository.setRepositoryMethodMetadata(
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class.getMethod("dummy")));
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreference.class, TestRepositoryWithReadPreference.class.getMethod("dummy")));
repository.findOne(Example.of(new TestDummy()));
@ -188,7 +188,7 @@ public class SimpleMongoRepositoryUnitTests { @@ -188,7 +188,7 @@ public class SimpleMongoRepositoryUnitTests {
repository = new SimpleMongoRepository<>(entityInformation, mongoOperations);
repository.setRepositoryMethodMetadata(
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreferenceMethod.class.getMethod("dummy")));
new DefaultCrudMethodMetadata(TestRepositoryWithReadPreferenceMethod.class, TestRepositoryWithReadPreferenceMethod.class.getMethod("dummy")));
repository.findBy(Example.of(new TestDummy()), FetchableFluentQuery::all);

Loading…
Cancel
Save