Resolve @ReadPreference on actual repository interface.
Original pull request: #4545 Closes #4542
This commit is contained in:
committed by
Mark Paluch
parent
db86097c0d
commit
e78e1978d5
@@ -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
|
||||
|
||||
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
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
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 {
|
||||
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user