Reduce API surface, expose interfaces only.
See #3270 Original pull request: #3271
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
@@ -43,6 +44,7 @@ import org.springframework.javapoet.JavaFile;
|
||||
import org.springframework.javapoet.MethodSpec;
|
||||
import org.springframework.javapoet.TypeName;
|
||||
import org.springframework.javapoet.TypeSpec;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Builder for AOT repository fragments.
|
||||
@@ -59,9 +61,9 @@ class AotRepositoryBuilder {
|
||||
private final ProjectionFactory projectionFactory;
|
||||
private final AotRepositoryFragmentMetadata generationMetadata;
|
||||
|
||||
private @Nullable ConstructorCustomizer constructorCustomizer;
|
||||
private @Nullable Consumer<AotRepositoryConstructorBuilder> constructorCustomizer;
|
||||
private @Nullable MethodContributorFactory methodContributorFactory;
|
||||
private ClassCustomizer customizer;
|
||||
private Consumer<AotRepositoryClassBuilder> classCustomizer;
|
||||
|
||||
private AotRepositoryBuilder(RepositoryInformation repositoryInformation, String moduleName,
|
||||
ProjectionFactory projectionFactory) {
|
||||
@@ -76,7 +78,7 @@ class AotRepositoryBuilder {
|
||||
.initializer("$T.getLog($T.class)", TypeName.get(LogFactory.class), this.generationMetadata.getTargetTypeName())
|
||||
.build());
|
||||
|
||||
this.customizer = (info, builder) -> {};
|
||||
this.classCustomizer = (builder) -> {};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,14 +95,14 @@ class AotRepositoryBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a {@link ClassCustomizer} customizer.
|
||||
* Configure a {@link AotRepositoryConstructorBuilder} customizer.
|
||||
*
|
||||
* @param classCustomizer must not be {@literal null}.
|
||||
* @return {@code this}.
|
||||
*/
|
||||
public AotRepositoryBuilder withClassCustomizer(ClassCustomizer classCustomizer) {
|
||||
public AotRepositoryBuilder withClassCustomizer(Consumer<AotRepositoryClassBuilder> classCustomizer) {
|
||||
|
||||
this.customizer = classCustomizer;
|
||||
this.classCustomizer = classCustomizer;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -110,7 +112,8 @@ class AotRepositoryBuilder {
|
||||
* @param constructorCustomizer must not be {@literal null}.
|
||||
* @return {@code this}.
|
||||
*/
|
||||
public AotRepositoryBuilder withConstructorCustomizer(ConstructorCustomizer constructorCustomizer) {
|
||||
public AotRepositoryBuilder withConstructorCustomizer(
|
||||
Consumer<AotRepositoryConstructorBuilder> constructorCustomizer) {
|
||||
|
||||
this.constructorCustomizer = constructorCustomizer;
|
||||
return this;
|
||||
@@ -162,7 +165,12 @@ class AotRepositoryBuilder {
|
||||
generationMetadata.getFields().values().forEach(builder::addField);
|
||||
|
||||
// finally customize the file itself
|
||||
this.customizer.customize(repositoryInformation, builder);
|
||||
this.classCustomizer.accept(customizer -> {
|
||||
|
||||
Assert.notNull(customizer, "ClassCustomizer must not be null");
|
||||
customizer.customize(builder);
|
||||
});
|
||||
|
||||
JavaFile javaFile = JavaFile.builder(packageName(), builder.build()).build();
|
||||
AotRepositoryMetadata metadata = getAotRepositoryMetadata(methodMetadata);
|
||||
|
||||
@@ -171,11 +179,11 @@ class AotRepositoryBuilder {
|
||||
|
||||
private MethodSpec buildConstructor() {
|
||||
|
||||
AotRepositoryConstructorBuilder constructorBuilder = new AotRepositoryConstructorBuilder(repositoryInformation,
|
||||
RepositoryConstructorBuilder constructorBuilder = new RepositoryConstructorBuilder(
|
||||
generationMetadata);
|
||||
|
||||
if (constructorCustomizer != null) {
|
||||
constructorCustomizer.customize(constructorBuilder);
|
||||
constructorCustomizer.accept(constructorBuilder);
|
||||
}
|
||||
|
||||
return constructorBuilder.buildConstructor();
|
||||
@@ -213,8 +221,7 @@ class AotRepositoryBuilder {
|
||||
|
||||
if (repositoryInformation.isQueryMethod(method) && methodContributorFactory != null) {
|
||||
|
||||
MethodContributor<? extends QueryMethod> contributor = methodContributorFactory.create(method,
|
||||
repositoryInformation);
|
||||
MethodContributor<? extends QueryMethod> contributor = methodContributorFactory.create(method);
|
||||
|
||||
if (contributor != null) {
|
||||
|
||||
@@ -273,20 +280,6 @@ class AotRepositoryBuilder {
|
||||
return projectionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customizer interface to customize the AOT repository fragment class after it has been defined.
|
||||
*/
|
||||
public interface ClassCustomizer {
|
||||
|
||||
/**
|
||||
* Apply customization ot the AOT repository fragment class after it has been defined.
|
||||
*
|
||||
* @param information the repository information that is used for the AOT fragment.
|
||||
* @param builder the class builder to be customized.
|
||||
*/
|
||||
void customize(RepositoryInformation information, TypeSpec.Builder builder);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Customizer interface to customize the AOT repository fragment constructor through
|
||||
@@ -313,12 +306,11 @@ class AotRepositoryBuilder {
|
||||
* Apply customization ot the AOT repository fragment constructor.
|
||||
*
|
||||
* @param method the method to be contributed.
|
||||
* @param information repository information.
|
||||
* @return the {@link MethodContributor} to be used. Can be {@literal null} if the method and method metadata should
|
||||
* not be contributed.
|
||||
*/
|
||||
@Nullable
|
||||
MethodContributor<? extends QueryMethod> create(Method method, RepositoryInformation information);
|
||||
MethodContributor<? extends QueryMethod> create(Method method);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2025 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.repository.aot.generate;
|
||||
|
||||
import org.springframework.javapoet.TypeSpec;
|
||||
|
||||
/**
|
||||
* Builder for AOT repository fragment classes.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 4.0
|
||||
*/
|
||||
public interface AotRepositoryClassBuilder {
|
||||
|
||||
/**
|
||||
* Add a class customizer. Customizer is invoked after building the class.
|
||||
*
|
||||
* @param customizer the customizer with direct access to the {@link TypeSpec.Builder type builder}.
|
||||
*/
|
||||
void customize(ClassCustomizer customizer);
|
||||
|
||||
/**
|
||||
* Customizer interface to customize the AOT repository fragment class after it has been defined.
|
||||
*/
|
||||
interface ClassCustomizer {
|
||||
|
||||
/**
|
||||
* Apply customization ot the AOT repository fragment class after it has been defined.
|
||||
*
|
||||
* @param builder the class builder to be customized.
|
||||
*/
|
||||
void customize(TypeSpec.Builder builder);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,15 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.repository.aot.generate;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.data.repository.aot.generate.AotRepositoryFragmentMetadata.ConstructorArgument;
|
||||
import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.javapoet.MethodSpec;
|
||||
import org.springframework.javapoet.ParameterizedTypeName;
|
||||
import org.springframework.javapoet.TypeName;
|
||||
|
||||
/**
|
||||
@@ -33,18 +25,7 @@ import org.springframework.javapoet.TypeName;
|
||||
* @author Mark Paluch
|
||||
* @since 4.0
|
||||
*/
|
||||
public class AotRepositoryConstructorBuilder {
|
||||
|
||||
private final RepositoryInformation repositoryInformation;
|
||||
private final AotRepositoryFragmentMetadata metadata;
|
||||
|
||||
private ConstructorCustomizer customizer = (info, builder) -> {};
|
||||
|
||||
AotRepositoryConstructorBuilder(RepositoryInformation repositoryInformation, AotRepositoryFragmentMetadata metadata) {
|
||||
|
||||
this.repositoryInformation = repositoryInformation;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
public interface AotRepositoryConstructorBuilder {
|
||||
|
||||
/**
|
||||
* Add constructor parameter and create a field storing its value.
|
||||
@@ -52,16 +33,7 @@ public class AotRepositoryConstructorBuilder {
|
||||
* @param parameterName name of the parameter.
|
||||
* @param type parameter type.
|
||||
*/
|
||||
public void addParameter(String parameterName, Class<?> type) {
|
||||
|
||||
ResolvableType resolvableType = ResolvableType.forClass(type);
|
||||
if (!resolvableType.hasGenerics() || !resolvableType.hasResolvableGenerics()) {
|
||||
addParameter(parameterName, TypeName.get(type));
|
||||
return;
|
||||
}
|
||||
|
||||
addParameter(parameterName, ParameterizedTypeName.get(type, resolvableType.resolveGenerics()));
|
||||
}
|
||||
void addParameter(String parameterName, Class<?> type);
|
||||
|
||||
/**
|
||||
* Add constructor parameter and create a field storing its value.
|
||||
@@ -69,7 +41,7 @@ public class AotRepositoryConstructorBuilder {
|
||||
* @param parameterName name of the parameter.
|
||||
* @param type parameter type.
|
||||
*/
|
||||
public void addParameter(String parameterName, TypeName type) {
|
||||
default void addParameter(String parameterName, TypeName type) {
|
||||
addParameter(parameterName, type, true);
|
||||
}
|
||||
|
||||
@@ -80,14 +52,7 @@ public class AotRepositoryConstructorBuilder {
|
||||
* @param type parameter type.
|
||||
* @param createField whether to create a field for the parameter and assign its value to the field.
|
||||
*/
|
||||
public void addParameter(String parameterName, TypeName type, boolean createField) {
|
||||
|
||||
this.metadata.addConstructorArgument(parameterName, type, createField ? parameterName : null);
|
||||
|
||||
if (createField) {
|
||||
this.metadata.addField(parameterName, type, Modifier.PRIVATE, Modifier.FINAL);
|
||||
}
|
||||
}
|
||||
void addParameter(String parameterName, TypeName type, boolean createField);
|
||||
|
||||
/**
|
||||
* Add constructor customizer. Customizer is invoked after adding constructor arguments and before assigning
|
||||
@@ -95,41 +60,19 @@ public class AotRepositoryConstructorBuilder {
|
||||
*
|
||||
* @param customizer the customizer with direct access to the {@link MethodSpec.Builder constructor builder}.
|
||||
*/
|
||||
public void customize(ConstructorCustomizer customizer) {
|
||||
this.customizer = customizer;
|
||||
}
|
||||
|
||||
MethodSpec buildConstructor() {
|
||||
|
||||
MethodSpec.Builder builder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
|
||||
|
||||
for (Entry<String, ConstructorArgument> parameter : this.metadata.getConstructorArguments().entrySet()) {
|
||||
builder.addParameter(parameter.getValue().typeName(), parameter.getKey());
|
||||
}
|
||||
|
||||
customizer.customize(repositoryInformation, builder);
|
||||
|
||||
for (Entry<String, ConstructorArgument> parameter : this.metadata.getConstructorArguments().entrySet()) {
|
||||
if (parameter.getValue().isForLocalField()) {
|
||||
builder.addStatement("this.$N = $N", parameter.getKey(), parameter.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
void customize(ConstructorCustomizer customizer);
|
||||
|
||||
/**
|
||||
* Customizer for the AOT repository constructor.
|
||||
*/
|
||||
public interface ConstructorCustomizer {
|
||||
interface ConstructorCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the constructor.
|
||||
*
|
||||
* @param information the repository information that is used for the AOT fragment.
|
||||
* @param builder the constructor builder to be customized.
|
||||
*/
|
||||
void customize(RepositoryInformation information, MethodSpec.Builder builder);
|
||||
void customize(MethodSpec.Builder builder);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2024 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.repository.aot.generate;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.data.repository.aot.generate.AotRepositoryFragmentMetadata.ConstructorArgument;
|
||||
import org.springframework.javapoet.MethodSpec;
|
||||
import org.springframework.javapoet.ParameterizedTypeName;
|
||||
import org.springframework.javapoet.TypeName;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Builder for AOT Repository Constructors.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 4.0
|
||||
*/
|
||||
class RepositoryConstructorBuilder implements AotRepositoryConstructorBuilder {
|
||||
|
||||
private final AotRepositoryFragmentMetadata metadata;
|
||||
|
||||
private ConstructorCustomizer customizer = (builder) -> {};
|
||||
|
||||
RepositoryConstructorBuilder(AotRepositoryFragmentMetadata metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add constructor parameter and create a field storing its value.
|
||||
*
|
||||
* @param parameterName name of the parameter.
|
||||
* @param type parameter type.
|
||||
*/
|
||||
@Override
|
||||
public void addParameter(String parameterName, Class<?> type) {
|
||||
|
||||
ResolvableType resolvableType = ResolvableType.forClass(type);
|
||||
if (!resolvableType.hasGenerics() || !resolvableType.hasResolvableGenerics()) {
|
||||
addParameter(parameterName, TypeName.get(type));
|
||||
return;
|
||||
}
|
||||
|
||||
addParameter(parameterName, ParameterizedTypeName.get(type, resolvableType.resolveGenerics()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add constructor parameter and create a field storing its value.
|
||||
*
|
||||
* @param parameterName name of the parameter.
|
||||
* @param type parameter type.
|
||||
*/
|
||||
@Override
|
||||
public void addParameter(String parameterName, TypeName type) {
|
||||
addParameter(parameterName, type, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add constructor parameter.
|
||||
*
|
||||
* @param parameterName name of the parameter.
|
||||
* @param type parameter type.
|
||||
* @param createField whether to create a field for the parameter and assign its value to the field.
|
||||
*/
|
||||
@Override
|
||||
public void addParameter(String parameterName, TypeName type, boolean createField) {
|
||||
|
||||
this.metadata.addConstructorArgument(parameterName, type, createField ? parameterName : null);
|
||||
|
||||
if (createField) {
|
||||
this.metadata.addField(parameterName, type, Modifier.PRIVATE, Modifier.FINAL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add constructor customizer. Customizer is invoked after adding constructor arguments and before assigning
|
||||
* constructor arguments to fields.
|
||||
*
|
||||
* @param customizer the customizer with direct access to the {@link MethodSpec.Builder constructor builder}.
|
||||
*/
|
||||
@Override
|
||||
public void customize(ConstructorCustomizer customizer) {
|
||||
|
||||
Assert.notNull(customizer, "ConstructorCustomizer must not be null");
|
||||
this.customizer = customizer;
|
||||
}
|
||||
|
||||
public MethodSpec buildConstructor() {
|
||||
|
||||
MethodSpec.Builder builder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
|
||||
|
||||
for (Entry<String, ConstructorArgument> parameter : this.metadata.getConstructorArguments().entrySet()) {
|
||||
builder.addParameter(parameter.getValue().typeName(), parameter.getKey());
|
||||
}
|
||||
|
||||
customizer.customize(builder);
|
||||
|
||||
for (Entry<String, ConstructorArgument> parameter : this.metadata.getConstructorArguments().entrySet()) {
|
||||
if (parameter.getValue().isForLocalField()) {
|
||||
builder.addStatement("this.$N = $N", parameter.getKey(), parameter.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.javapoet.JavaFile;
|
||||
import org.springframework.javapoet.TypeName;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.javapoet.TypeSpec;
|
||||
|
||||
/**
|
||||
@@ -136,23 +137,21 @@ public class RepositoryContributor {
|
||||
/**
|
||||
* Customization hook for store implementations to customize class after building the entire class.
|
||||
*/
|
||||
protected void customizeClass(RepositoryInformation information,
|
||||
TypeSpec.Builder builder) {
|
||||
protected void customizeClass(AotRepositoryClassBuilder builder) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Customization hook for store implementations to customize the fragment constructor after building the constructor.
|
||||
*/
|
||||
protected void customizeConstructor(AotRepositoryConstructorBuilder constructorBuilder) {
|
||||
protected void customizeConstructor(AotRepositoryConstructorBuilder builder) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Customization hook for store implementations to contribute a query method.
|
||||
*/
|
||||
protected @Nullable MethodContributor<? extends QueryMethod> contributeQueryMethod(Method method,
|
||||
RepositoryInformation repositoryInformation) {
|
||||
protected @Nullable MethodContributor<? extends QueryMethod> contributeQueryMethod(Method method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ class AotRepositoryBuilderUnitTests {
|
||||
AotRepositoryBuilder repoBuilder = AotRepositoryBuilder.forRepository(repositoryInformation, "Commons",
|
||||
new SpelAwareProxyProjectionFactory());
|
||||
repoBuilder.withConstructorCustomizer(ctor -> {
|
||||
ctor.customize((info, code) -> {
|
||||
ctor.customize((code) -> {
|
||||
code.addStatement("throw new $T($S)", IllegalStateException.class, "initialization error");
|
||||
});
|
||||
});
|
||||
@@ -110,7 +110,9 @@ class AotRepositoryBuilderUnitTests {
|
||||
AotRepositoryBuilder repoBuilder = AotRepositoryBuilder.forRepository(repositoryInformation, "Commons",
|
||||
new SpelAwareProxyProjectionFactory());
|
||||
|
||||
repoBuilder.withClassCustomizer((info, metadata, clazz) -> {
|
||||
repoBuilder.withClassCustomizer((builder) -> {
|
||||
|
||||
builder.customize(clazz -> {
|
||||
|
||||
clazz.addField(Float.class, "f", Modifier.PRIVATE, Modifier.STATIC);
|
||||
clazz.addField(Double.class, "d", Modifier.PUBLIC);
|
||||
@@ -119,6 +121,7 @@ class AotRepositoryBuilderUnitTests {
|
||||
clazz.addAnnotation(Repository.class);
|
||||
|
||||
clazz.addMethod(MethodSpec.methodBuilder("oops").build());
|
||||
});
|
||||
});
|
||||
|
||||
assertThat(repoBuilder.build().javaFile().toString()) //
|
||||
@@ -138,7 +141,7 @@ class AotRepositoryBuilderUnitTests {
|
||||
AotRepositoryBuilder repoBuilder = AotRepositoryBuilder.forRepository(repositoryInformation, "Commons",
|
||||
new SpelAwareProxyProjectionFactory());
|
||||
|
||||
repoBuilder.withQueryMethodContributor((method, info) -> {
|
||||
repoBuilder.withQueryMethodContributor((method) -> {
|
||||
|
||||
return new MethodContributor<>(mock(QueryMethod.class), null) {
|
||||
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.repository.aot.generate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import org.assertj.core.api.MapAssert;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.data.repository.config.AotRepositoryContext;
|
||||
import org.springframework.data.repository.core.RepositoryInformation;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
@@ -41,8 +41,7 @@ public class MethodCapturingRepositoryContributor extends RepositoryContributor
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable MethodContributor<? extends QueryMethod> contributeQueryMethod(Method method,
|
||||
RepositoryInformation repositoryInformation) {
|
||||
protected @Nullable MethodContributor<? extends QueryMethod> contributeQueryMethod(Method method) {
|
||||
capturedInvocations.add(method.getName(), method);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -58,10 +58,10 @@ class RepositoryContributorUnitTests {
|
||||
RepositoryContributor repositoryContributor = new RepositoryContributor(aotContext) {
|
||||
|
||||
@Override
|
||||
protected @Nullable MethodContributor<? extends QueryMethod> contributeQueryMethod(Method method,
|
||||
RepositoryInformation repositoryInformation) {
|
||||
protected @Nullable MethodContributor<? extends QueryMethod> contributeQueryMethod(Method method) {
|
||||
|
||||
return MethodContributor.forQueryMethod(new QueryMethod(method, repositoryInformation, getProjectionFactory()))
|
||||
return MethodContributor
|
||||
.forQueryMethod(new QueryMethod(method, getRepositoryInformation(), getProjectionFactory()))
|
||||
.withMetadata(new QueryMetadata() {
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user