1919
2020import java .lang .reflect .Method ;
2121import java .lang .reflect .Modifier ;
22- import java .util .Collections ;
23- import java .util .HashSet ;
22+ import java .util .Arrays ;
2423import java .util .Set ;
2524import java .util .function .Supplier ;
2625
@@ -43,6 +42,7 @@ public abstract class RepositoryInformationSupport implements RepositoryInformat
4342
4443 private final Supplier <RepositoryMetadata > metadata ;
4544 private final Supplier <Class <?>> repositoryBaseClass ;
45+ private final Supplier <DefaultQueryMethods > queryMethods ;
4646
4747 public RepositoryInformationSupport (Supplier <RepositoryMetadata > metadata , Supplier <Class <?>> repositoryBaseClass ) {
4848
@@ -51,25 +51,12 @@ public RepositoryInformationSupport(Supplier<RepositoryMetadata> metadata, Suppl
5151
5252 this .metadata = Lazy .of (metadata );
5353 this .repositoryBaseClass = Lazy .of (repositoryBaseClass );
54+ this .queryMethods = Lazy .of (this ::calculateQueryMethods );
5455 }
5556
5657 @ Override
5758 public Streamable <Method > getQueryMethods () {
58-
59- Set <Method > result = new HashSet <>();
60-
61- for (Method method : getRepositoryInterface ().getMethods ()) {
62- method = ClassUtils .getMostSpecificMethod (method , getRepositoryInterface ());
63- if (isQueryMethodCandidate (method )) {
64- result .add (method );
65- }
66- }
67-
68- return Streamable .of (Collections .unmodifiableSet (result ));
69- }
70-
71- private RepositoryMetadata getMetadata () {
72- return metadata .get ();
59+ return queryMethods .get ().methods ;
7360 }
7461
7562 @ Override
@@ -139,21 +126,12 @@ public TypeInformation<?> getIdTypeInformation() {
139126
140127 @ Override
141128 public boolean hasCustomMethod () {
129+ return queryMethods .get ().hasCustomMethod ;
130+ }
142131
143- Class <?> repositoryInterface = getRepositoryInterface ();
144-
145- // No detection required if no typing interface was configured
146- if (isGenericRepositoryInterface (repositoryInterface )) {
147- return false ;
148- }
149-
150- for (Method method : repositoryInterface .getMethods ()) {
151- if (isCustomMethod (method ) && !isBaseClassMethod (method )) {
152- return true ;
153- }
154- }
155-
156- return false ;
132+ @ Override
133+ public boolean hasQueryMethods () {
134+ return queryMethods .get ().hasQueryMethod ;
157135 }
158136
159137 /**
@@ -178,4 +156,52 @@ protected boolean isQueryMethodCandidate(Method method) {
178156 && !Modifier .isStatic (method .getModifiers ()) //
179157 && (isQueryAnnotationPresentOn (method ) || !isCustomMethod (method ) && !isBaseClassMethod (method ));
180158 }
159+
160+ private RepositoryMetadata getMetadata () {
161+ return metadata .get ();
162+ }
163+
164+ private final DefaultQueryMethods calculateQueryMethods () {
165+
166+ Class <?> repositoryInterface = getRepositoryInterface ();
167+
168+ return new DefaultQueryMethods (Streamable .of (Arrays .stream (repositoryInterface .getMethods ())
169+ .map (it -> ClassUtils .getMostSpecificMethod (it , repositoryInterface ))
170+ .filter (this ::isQueryMethodCandidate )
171+ .toList ()), calculateHasCustomMethod (repositoryInterface ));
172+ }
173+
174+ private final boolean calculateHasCustomMethod (Class <?> repositoryInterface ) {
175+
176+ // No detection required if no typing interface was configured
177+ if (isGenericRepositoryInterface (repositoryInterface )) {
178+ return false ;
179+ }
180+
181+ for (Method method : repositoryInterface .getMethods ()) {
182+ if (isCustomMethod (method ) && !isBaseClassMethod (method )) {
183+ return true ;
184+ }
185+ }
186+
187+ return false ;
188+ }
189+
190+ /**
191+ * Information about query methods to allow canonical computation and reuse of that information.
192+ *
193+ * @author Oliver Drotbohm
194+ */
195+ private static class DefaultQueryMethods {
196+
197+ private final Streamable <Method > methods ;
198+ private final boolean hasCustomMethod , hasQueryMethod ;
199+
200+ DefaultQueryMethods (Streamable <Method > methods , boolean hasCustomMethod ) {
201+
202+ this .methods = methods ;
203+ this .hasCustomMethod = hasCustomMethod ;
204+ this .hasQueryMethod = !methods .isEmpty ();
205+ }
206+ }
181207}
0 commit comments