@@ -107,7 +107,7 @@ public abstract class RepositoryFactorySupport
107107 CONVERSION_SERVICE .removeConvertible (Object .class , Object .class );
108108 }
109109
110- private final Map <RepositoryInformationCacheKey , RepositoryInformation > repositoryInformationCache ;
110+ private final Map <RepositoryInformationCacheKey , RepositoryStub > repositoryInformationCache ;
111111 private final List <RepositoryProxyPostProcessor > postProcessors ;
112112
113113 private @ Nullable Class <?> repositoryBaseClass ;
@@ -127,7 +127,7 @@ public abstract class RepositoryFactorySupport
127127 @ SuppressWarnings ("null" )
128128 public RepositoryFactorySupport () {
129129
130- this .repositoryInformationCache = new HashMap <>(16 );
130+ this .repositoryInformationCache = new HashMap <>(8 );
131131 this .postProcessors = new ArrayList <>();
132132
133133 this .namedQueries = PropertiesBasedNamedQueries .EMPTY ;
@@ -291,16 +291,6 @@ protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata
291291 return RepositoryFragments .empty ();
292292 }
293293
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-
304294 /**
305295 * Returns a repository instance for the given interface.
306296 *
@@ -359,8 +349,9 @@ public <T> T getRepository(Class<T> repositoryInterface, RepositoryFragments fra
359349 repositoryInterface );
360350 repositoryCompositionStep .tag ("fragment.count" , String .valueOf (fragments .size ()));
361351
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 ();
364355
365356 repositoryCompositionStep .tag ("fragments" , () -> {
366357
@@ -490,47 +481,35 @@ protected RepositoryMetadata getRepositoryMetadata(Class<?> repositoryInterface)
490481 * @return will never be {@literal null}.
491482 */
492483 protected RepositoryInformation getRepositoryInformation (RepositoryMetadata metadata , RepositoryFragments fragments ) {
493- return getRepositoryInformation (metadata , getRepositoryComposition ( metadata , fragments ));
484+ return getRepositoryStub (metadata , fragments ). information ( );
494485 }
495486
496487 /**
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.
517493 *
518494 * @param metadata
519- * @param composition
495+ * @param fragments
520496 * @return
521497 */
522- private RepositoryInformation getRepositoryInformation (RepositoryMetadata metadata ,
523- RepositoryComposition composition ) {
498+ private RepositoryStub getRepositoryStub (RepositoryMetadata metadata , RepositoryFragments fragments ) {
524499
525- RepositoryInformationCacheKey cacheKey = new RepositoryInformationCacheKey (metadata , composition );
500+ RepositoryInformationCacheKey cacheKey = new RepositoryInformationCacheKey (metadata , fragments );
526501
527502 synchronized (repositoryInformationCache ) {
528503
529504 return repositoryInformationCache .computeIfAbsent (cacheKey , key -> {
530505
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 );
532509
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 );
534513 });
535514 }
536515 }
@@ -811,6 +790,18 @@ public List<QueryMethod> getQueryMethods() {
811790 }
812791 }
813792
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+
814805 /**
815806 * Simple value object to build up keys to cache {@link RepositoryInformation} instances.
816807 *
@@ -820,31 +811,26 @@ public List<QueryMethod> getQueryMethods() {
820811 private static final class RepositoryInformationCacheKey {
821812
822813 private final String repositoryInterfaceName ;
823- private final long compositionHash ;
814+ private final long fragmentsHash ;
824815
825816 /**
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 .
827818 *
828819 * @param metadata must not be {@literal null}.
829- * @param composition must not be {@literal null}.
820+ * @param fragments must not be {@literal null}.
830821 */
831- public RepositoryInformationCacheKey (RepositoryMetadata metadata , RepositoryComposition composition ) {
822+ public RepositoryInformationCacheKey (RepositoryMetadata metadata , RepositoryFragments fragments ) {
832823
833824 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 ();
840826 }
841827
842828 public String getRepositoryInterfaceName () {
843829 return this .repositoryInterfaceName ;
844830 }
845831
846- public long getCompositionHash () {
847- return this .compositionHash ;
832+ public long getFragmentsHash () {
833+ return this .fragmentsHash ;
848834 }
849835
850836 @ Override
@@ -855,7 +841,7 @@ public boolean equals(Object o) {
855841 if (!(o instanceof RepositoryInformationCacheKey that )) {
856842 return false ;
857843 }
858- if (compositionHash != that .compositionHash ) {
844+ if (fragmentsHash != that .fragmentsHash ) {
859845 return false ;
860846 }
861847 return ObjectUtils .nullSafeEquals (repositoryInterfaceName , that .repositoryInterfaceName );
@@ -864,14 +850,14 @@ public boolean equals(Object o) {
864850 @ Override
865851 public int hashCode () {
866852 int result = ObjectUtils .nullSafeHashCode (repositoryInterfaceName );
867- result = 31 * result + ( int ) ( compositionHash ^ ( compositionHash >>> 32 ) );
853+ result = 31 * result + Long . hashCode ( fragmentsHash );
868854 return result ;
869855 }
870856
871857 @ Override
872858 public String toString () {
873859 return "RepositoryFactorySupport.RepositoryInformationCacheKey(repositoryInterfaceName="
874- + this .getRepositoryInterfaceName () + ", compositionHash =" + this .getCompositionHash () + ")" ;
860+ + this .getRepositoryInterfaceName () + ", fragmentsHash =" + this .getFragmentsHash () + ")" ;
875861 }
876862 }
877863
0 commit comments