@@ -107,7 +107,7 @@ public abstract class RepositoryFactorySupport
107
107
CONVERSION_SERVICE .removeConvertible (Object .class , Object .class );
108
108
}
109
109
110
- private final Map <RepositoryInformationCacheKey , RepositoryInformation > repositoryInformationCache ;
110
+ private final Map <RepositoryInformationCacheKey , RepositoryStub > repositoryInformationCache ;
111
111
private final List <RepositoryProxyPostProcessor > postProcessors ;
112
112
113
113
private @ Nullable Class <?> repositoryBaseClass ;
@@ -127,7 +127,7 @@ public abstract class RepositoryFactorySupport
127
127
@ SuppressWarnings ("null" )
128
128
public RepositoryFactorySupport () {
129
129
130
- this .repositoryInformationCache = new HashMap <>(16 );
130
+ this .repositoryInformationCache = new HashMap <>(8 );
131
131
this .postProcessors = new ArrayList <>();
132
132
133
133
this .namedQueries = PropertiesBasedNamedQueries .EMPTY ;
@@ -291,16 +291,6 @@ protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata
291
291
return RepositoryFragments .empty ();
292
292
}
293
293
294
- /**
295
- * Creates {@link RepositoryComposition} based on {@link RepositoryMetadata} for repository-specific method handling.
296
- *
297
- * @param metadata the repository metadata to use.
298
- * @return repository composition.
299
- */
300
- private RepositoryComposition getRepositoryComposition (RepositoryMetadata metadata ) {
301
- return RepositoryComposition .fromMetadata (metadata );
302
- }
303
-
304
294
/**
305
295
* Returns a repository instance for the given interface.
306
296
*
@@ -359,8 +349,9 @@ public <T> T getRepository(Class<T> repositoryInterface, RepositoryFragments fra
359
349
repositoryInterface );
360
350
repositoryCompositionStep .tag ("fragment.count" , String .valueOf (fragments .size ()));
361
351
362
- RepositoryComposition composition = getRepositoryComposition (metadata , fragments );
363
- RepositoryInformation information = getRepositoryInformation (metadata , composition );
352
+ RepositoryStub stub = getRepositoryStub (metadata , fragments );
353
+ RepositoryComposition composition = stub .composition ();
354
+ RepositoryInformation information = stub .information ();
364
355
365
356
repositoryCompositionStep .tag ("fragments" , () -> {
366
357
@@ -490,47 +481,35 @@ protected RepositoryMetadata getRepositoryMetadata(Class<?> repositoryInterface)
490
481
* @return will never be {@literal null}.
491
482
*/
492
483
protected RepositoryInformation getRepositoryInformation (RepositoryMetadata metadata , RepositoryFragments fragments ) {
493
- return getRepositoryInformation (metadata , getRepositoryComposition ( metadata , fragments ));
484
+ return getRepositoryStub (metadata , fragments ). information ( );
494
485
}
495
486
496
487
/**
497
- * Returns the {@link RepositoryComposition} for the given {@link RepositoryMetadata} and extra
498
- * {@link RepositoryFragments}.
499
- *
500
- * @param metadata must not be {@literal null}.
501
- * @param fragments must not be {@literal null}.
502
- * @return will never be {@literal null}.
503
- */
504
- private RepositoryComposition getRepositoryComposition (RepositoryMetadata metadata , RepositoryFragments fragments ) {
505
-
506
- Assert .notNull (metadata , "RepositoryMetadata must not be null" );
507
- Assert .notNull (fragments , "RepositoryFragments must not be null" );
508
-
509
- RepositoryComposition composition = getRepositoryComposition (metadata );
510
- RepositoryFragments repositoryAspects = getRepositoryFragments (metadata );
511
-
512
- return composition .append (fragments ).append (repositoryAspects );
513
- }
514
-
515
- /**
516
- * Returns the {@link RepositoryInformation} for the given repository interface.
488
+ * Returns the cached {@link RepositoryStub} for the given repository and composition. {@link RepositoryMetadata} is a
489
+ * strong cache key while {@link RepositoryFragments} contributes a light-weight caching component by using only the
490
+ * fragments hash code. In a typical Spring scenario, that shouldn't impose issues as one repository factory produces
491
+ * only a single repository instance for one repository interface. Things might be different when using various
492
+ * fragments for the same repository interface.
517
493
*
518
494
* @param metadata
519
- * @param composition
495
+ * @param fragments
520
496
* @return
521
497
*/
522
- private RepositoryInformation getRepositoryInformation (RepositoryMetadata metadata ,
523
- RepositoryComposition composition ) {
498
+ private RepositoryStub getRepositoryStub (RepositoryMetadata metadata , RepositoryFragments fragments ) {
524
499
525
- RepositoryInformationCacheKey cacheKey = new RepositoryInformationCacheKey (metadata , composition );
500
+ RepositoryInformationCacheKey cacheKey = new RepositoryInformationCacheKey (metadata , fragments );
526
501
527
502
synchronized (repositoryInformationCache ) {
528
503
529
504
return repositoryInformationCache .computeIfAbsent (cacheKey , key -> {
530
505
531
- Class <?> baseClass = repositoryBaseClass != null ? repositoryBaseClass : getRepositoryBaseClass (metadata );
506
+ RepositoryComposition composition = RepositoryComposition .fromMetadata (metadata );
507
+ RepositoryFragments repositoryAspects = getRepositoryFragments (metadata );
508
+ composition = composition .append (fragments ).append (repositoryAspects );
532
509
533
- return new DefaultRepositoryInformation (metadata , baseClass , composition );
510
+ Class <?> baseClass = repositoryBaseClass != null ? repositoryBaseClass : getRepositoryBaseClass (metadata );
511
+
512
+ return new RepositoryStub (new DefaultRepositoryInformation (metadata , baseClass , composition ), composition );
534
513
});
535
514
}
536
515
}
@@ -811,6 +790,18 @@ public List<QueryMethod> getQueryMethods() {
811
790
}
812
791
}
813
792
793
+ /**
794
+ * Repository stub holding {@link RepositoryInformation} and {@link RepositoryComposition}.
795
+ *
796
+ * @param information
797
+ * @param composition
798
+ * @author Mark Paluch
799
+ * @since 3.4.4
800
+ */
801
+ record RepositoryStub (RepositoryInformation information , RepositoryComposition composition ) {
802
+
803
+ }
804
+
814
805
/**
815
806
* Simple value object to build up keys to cache {@link RepositoryInformation} instances.
816
807
*
@@ -820,31 +811,26 @@ public List<QueryMethod> getQueryMethods() {
820
811
private static final class RepositoryInformationCacheKey {
821
812
822
813
private final String repositoryInterfaceName ;
823
- private final long compositionHash ;
814
+ private final long fragmentsHash ;
824
815
825
816
/**
826
- * Creates a new {@link RepositoryInformationCacheKey} for the given {@link RepositoryMetadata} and composition .
817
+ * Creates a new {@link RepositoryInformationCacheKey} for the given {@link RepositoryMetadata} and fragments .
827
818
*
828
819
* @param metadata must not be {@literal null}.
829
- * @param composition must not be {@literal null}.
820
+ * @param fragments must not be {@literal null}.
830
821
*/
831
- public RepositoryInformationCacheKey (RepositoryMetadata metadata , RepositoryComposition composition ) {
822
+ public RepositoryInformationCacheKey (RepositoryMetadata metadata , RepositoryFragments fragments ) {
832
823
833
824
this .repositoryInterfaceName = metadata .getRepositoryInterface ().getName ();
834
- this .compositionHash = composition .hashCode ();
835
- }
836
-
837
- public RepositoryInformationCacheKey (String repositoryInterfaceName , long compositionHash ) {
838
- this .repositoryInterfaceName = repositoryInterfaceName ;
839
- this .compositionHash = compositionHash ;
825
+ this .fragmentsHash = fragments .getFragments ().hashCode ();
840
826
}
841
827
842
828
public String getRepositoryInterfaceName () {
843
829
return this .repositoryInterfaceName ;
844
830
}
845
831
846
- public long getCompositionHash () {
847
- return this .compositionHash ;
832
+ public long getFragmentsHash () {
833
+ return this .fragmentsHash ;
848
834
}
849
835
850
836
@ Override
@@ -855,7 +841,7 @@ public boolean equals(Object o) {
855
841
if (!(o instanceof RepositoryInformationCacheKey that )) {
856
842
return false ;
857
843
}
858
- if (compositionHash != that .compositionHash ) {
844
+ if (fragmentsHash != that .fragmentsHash ) {
859
845
return false ;
860
846
}
861
847
return ObjectUtils .nullSafeEquals (repositoryInterfaceName , that .repositoryInterfaceName );
@@ -864,14 +850,14 @@ public boolean equals(Object o) {
864
850
@ Override
865
851
public int hashCode () {
866
852
int result = ObjectUtils .nullSafeHashCode (repositoryInterfaceName );
867
- result = 31 * result + ( int ) ( compositionHash ^ ( compositionHash >>> 32 ) );
853
+ result = 31 * result + Long . hashCode ( fragmentsHash );
868
854
return result ;
869
855
}
870
856
871
857
@ Override
872
858
public String toString () {
873
859
return "RepositoryFactorySupport.RepositoryInformationCacheKey(repositoryInterfaceName="
874
- + this .getRepositoryInterfaceName () + ", compositionHash =" + this .getCompositionHash () + ")" ;
860
+ + this .getRepositoryInterfaceName () + ", fragmentsHash =" + this .getFragmentsHash () + ")" ;
875
861
}
876
862
}
877
863
0 commit comments