Browse Source

DATACMNS-389 - RepositoryFactorySupport now caches RepositoryInformation.

Instead of creating a new DefaultRepositoryInformation for each call to getRepositoryInformation(…) we now actively cache the created instances per repository type and custom implementation class.
pull/56/head
Oliver Gierke 12 years ago
parent
commit
5a6cefc4a9
  1. 72
      src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java

72
src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java

@ -20,6 +20,7 @@ import static org.springframework.util.ReflectionUtils.*; @@ -20,6 +20,7 @@ import static org.springframework.util.ReflectionUtils.*;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -40,6 +41,7 @@ import org.springframework.data.repository.query.QueryMethod; @@ -40,6 +41,7 @@ import org.springframework.data.repository.query.QueryMethod;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.data.repository.util.ClassUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Factory bean to create instances of a given repository interface. Creates a proxy implementing the configured
@ -50,6 +52,8 @@ import org.springframework.util.Assert; @@ -50,6 +52,8 @@ import org.springframework.util.Assert;
*/
public abstract class RepositoryFactorySupport implements BeanClassLoaderAware {
private static final Map<RepositoryInformationCacheKey, RepositoryInformation> REPOSITORY_INFORMATION_CACHE = new HashMap<RepositoryInformationCacheKey, RepositoryInformation>();
private final List<RepositoryProxyPostProcessor> postProcessors = new ArrayList<RepositoryProxyPostProcessor>();
private QueryLookupStrategy.Key queryLookupStrategyKey;
private List<QueryCreationListener<?>> queryPostProcessors = new ArrayList<QueryCreationListener<?>>();
@ -122,7 +126,6 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware { @@ -122,7 +126,6 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware {
* @return
*/
public <T> T getRepository(Class<T> repositoryInterface) {
return getRepository(repositoryInterface, null);
}
@ -180,7 +183,18 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware { @@ -180,7 +183,18 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware {
*/
protected RepositoryInformation getRepositoryInformation(RepositoryMetadata metadata,
Class<?> customImplementationClass) {
return new DefaultRepositoryInformation(metadata, getRepositoryBaseClass(metadata), customImplementationClass);
RepositoryInformationCacheKey cacheKey = new RepositoryInformationCacheKey(metadata, customImplementationClass);
RepositoryInformation repositoryInformation = REPOSITORY_INFORMATION_CACHE.get(cacheKey);
if (repositoryInformation != null) {
return repositoryInformation;
}
repositoryInformation = new DefaultRepositoryInformation(metadata, getRepositoryBaseClass(metadata),
customImplementationClass);
REPOSITORY_INFORMATION_CACHE.put(cacheKey, repositoryInformation);
return repositoryInformation;
}
protected List<QueryMethod> getQueryMethods() {
@ -403,4 +417,58 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware { @@ -403,4 +417,58 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware {
this.queryMethods.add(query.getQueryMethod());
}
}
/**
* Simple value object to build up keys to cache {@link RepositoryInformation} instances.
*
* @author Oliver Gierke
*/
private static class RepositoryInformationCacheKey {
private final String repositoryInterfaceName;
private final String customImplementationClassName;
/**
* Creates a new {@link RepositoryInformationCacheKey} for the given {@link RepositoryMetadata} and cuytom
* implementation type.
*
* @param repositoryInterfaceName must not be {@literal null}.
* @param customImplementationClassName
*/
public RepositoryInformationCacheKey(RepositoryMetadata metadata, Class<?> customImplementationType) {
this.repositoryInterfaceName = metadata.getRepositoryInterface().getName();
this.customImplementationClassName = customImplementationType == null ? null : customImplementationType.getName();
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof RepositoryInformationCacheKey)) {
return false;
}
RepositoryInformationCacheKey that = (RepositoryInformationCacheKey) obj;
return this.repositoryInterfaceName.equals(that.repositoryInterfaceName)
&& ObjectUtils.nullSafeEquals(this.customImplementationClassName, that.customImplementationClassName);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int result = 31;
result += 17 * repositoryInterfaceName.hashCode();
result += 17 * ObjectUtils.nullSafeHashCode(customImplementationClassName);
return result;
}
}
}

Loading…
Cancel
Save