Skip to content

Commit bac5ee8

Browse files
committed
Revise ClassUtils and ReflectionUtils.
We deprecated `ClassUtils` in the repo.utils package and introduced a slimmer variant in o.s.d.util. Also, ReflectionUtils hosts now several methods that have been in ClassUtils along with an improved method naming (find vs. get in combination with return value semantics). CastUtils is deprecated as we do not widely use it.
1 parent 5e2c751 commit bac5ee8

17 files changed

+310
-86
lines changed

src/main/java/org/springframework/data/mapping/model/AbstractPersistentProperty.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
4949

5050
static {
5151

52-
CAUSE_FIELD = ReflectionUtils.findRequiredField(Throwable.class, "cause");
52+
CAUSE_FIELD = ReflectionUtils.getRequiredField(Throwable.class, "cause");
5353
ASSOCIATION_TYPE = ReflectionUtils.loadIfPresent("org.jmolecules.ddd.types.Association",
5454
AbstractPersistentProperty.class.getClassLoader());
5555
}

src/main/java/org/springframework/data/querydsl/binding/QuerydslPredicateBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ private static TypeDescriptor getTargetTypeDescriptor(PathInformation path) {
219219

220220
TypeDescriptor result = descriptor == null //
221221
? TypeDescriptor
222-
.nested(org.springframework.data.util.ReflectionUtils.findRequiredField(owningType, leafProperty), 0)
222+
.nested(org.springframework.data.util.ReflectionUtils.getRequiredField(owningType, leafProperty), 0)
223223
: TypeDescriptor
224224
.nested(new Property(owningType, descriptor.getReadMethod(), descriptor.getWriteMethod(), leafProperty), 0);
225225

src/main/java/org/springframework/data/repository/config/RepositoryComponentProvider.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
import org.springframework.data.repository.NoRepositoryBean;
3434
import org.springframework.data.repository.Repository;
3535
import org.springframework.data.repository.RepositoryDefinition;
36-
import org.springframework.data.repository.util.ClassUtils;
3736
import org.springframework.lang.NonNull;
37+
import org.springframework.lang.Nullable;
3838
import org.springframework.util.Assert;
3939

4040
/**
@@ -103,7 +103,7 @@ public void addIncludeFilter(TypeFilter includeFilter) {
103103
@Override
104104
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
105105

106-
boolean isNonRepositoryInterface = !ClassUtils.isGenericRepositoryInterface(beanDefinition.getBeanClassName());
106+
boolean isNonRepositoryInterface = !isGenericRepositoryInterface(beanDefinition.getBeanClassName());
107107
boolean isTopLevelType = !beanDefinition.getMetadata().hasEnclosingClass();
108108
boolean isConsiderNestedRepositories = isConsiderNestedRepositoryInterfaces();
109109

@@ -150,6 +150,13 @@ public void setConsiderNestedRepositoryInterfaces(boolean considerNestedReposito
150150
this.considerNestedRepositoryInterfaces = considerNestedRepositoryInterfaces;
151151
}
152152

153+
/**
154+
* Returns whether the given type name is a {@link Repository} interface name.
155+
*/
156+
private static boolean isGenericRepositoryInterface(@Nullable String interfaceName) {
157+
return Repository.class.getName().equals(interfaceName);
158+
}
159+
153160
/**
154161
* {@link org.springframework.core.type.filter.TypeFilter} that only matches interfaces. Thus setting this up makes
155162
* only sense providing an interface type as {@code targetType}.
@@ -180,21 +187,19 @@ public boolean match(MetadataReader metadataReader, MetadataReaderFactory metada
180187
*
181188
* @author Oliver Gierke
182189
*/
183-
private static class AllTypeFilter implements TypeFilter {
184-
185-
private final List<TypeFilter> delegates;
190+
private record AllTypeFilter(List<TypeFilter> delegates) implements TypeFilter {
186191

187192
/**
188193
* Creates a new {@link AllTypeFilter} to match if all the given delegates match.
189194
*
190195
* @param delegates must not be {@literal null}.
191196
*/
192-
public AllTypeFilter(List<TypeFilter> delegates) {
197+
private AllTypeFilter {
193198

194199
Assert.notNull(delegates, "TypeFilter deleages must not be null");
195-
this.delegates = delegates;
196200
}
197201

202+
@Override
198203
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
199204
throws IOException {
200205

src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import org.apache.commons.logging.Log;
2828
import org.apache.commons.logging.LogFactory;
29+
2930
import org.springframework.beans.factory.config.BeanDefinition;
3031
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
3132
import org.springframework.beans.factory.config.DependencyDescriptor;
@@ -51,10 +52,9 @@
5152
import org.springframework.data.repository.core.support.AbstractRepositoryMetadata;
5253
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
5354
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
54-
import org.springframework.data.util.ReflectionUtils;
55+
import org.springframework.data.util.ClassUtils;
5556
import org.springframework.lang.Nullable;
5657
import org.springframework.util.Assert;
57-
import org.springframework.util.ClassUtils;
5858
import org.springframework.util.StopWatch;
5959

6060
/**
@@ -123,8 +123,7 @@ private static Environment defaultEnvironment(@Nullable Environment environment,
123123
return environment;
124124
}
125125

126-
return resourceLoader instanceof EnvironmentCapable capable ? capable.getEnvironment()
127-
: new StandardEnvironment();
126+
return resourceLoader instanceof EnvironmentCapable capable ? capable.getEnvironment() : new StandardEnvironment();
128127
}
129128

130129
/**
@@ -321,19 +320,19 @@ private static ApplicationStartup getStartup(BeanDefinitionRegistry registry) {
321320
private ResolvableType getRepositoryFactoryBeanType(RepositoryConfiguration<?> configuration) {
322321

323322
String interfaceName = configuration.getRepositoryInterface();
324-
ClassLoader classLoader = resourceLoader.getClassLoader() == null ? ClassUtils.getDefaultClassLoader()
323+
ClassLoader classLoader = resourceLoader.getClassLoader() == null
324+
? org.springframework.util.ClassUtils.getDefaultClassLoader()
325325
: resourceLoader.getClassLoader();
326326

327327
classLoader = classLoader != null ? classLoader : getClass().getClassLoader();
328328

329-
Class<?> repositoryInterface = ReflectionUtils.loadIfPresent(interfaceName, classLoader);
329+
Class<?> repositoryInterface = ClassUtils.loadIfPresent(interfaceName, classLoader);
330330

331331
if (repositoryInterface == null) {
332332
return null;
333333
}
334334

335-
Class<?> factoryBean = ReflectionUtils.loadIfPresent(configuration.getRepositoryFactoryBeanClassName(),
336-
classLoader);
335+
Class<?> factoryBean = ClassUtils.loadIfPresent(configuration.getRepositoryFactoryBeanClassName(), classLoader);
337336

338337
if (factoryBean == null) {
339338
return null;

src/main/java/org/springframework/data/repository/core/RepositoryInformationSupport.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
*/
1616
package org.springframework.data.repository.core;
1717

18-
import static org.springframework.data.repository.util.ClassUtils.*;
19-
2018
import java.lang.reflect.Method;
2119
import java.lang.reflect.Modifier;
2220
import java.util.Arrays;
@@ -25,9 +23,12 @@
2523

2624
import org.springframework.core.annotation.AnnotationUtils;
2725
import org.springframework.data.annotation.QueryAnnotation;
26+
import org.springframework.data.repository.Repository;
2827
import org.springframework.data.util.Lazy;
2928
import org.springframework.data.util.Streamable;
3029
import org.springframework.data.util.TypeInformation;
30+
import org.springframework.lang.Contract;
31+
import org.springframework.lang.Nullable;
3132
import org.springframework.util.Assert;
3233
import org.springframework.util.ClassUtils;
3334

@@ -166,8 +167,8 @@ private final DefaultQueryMethods calculateQueryMethods() {
166167
Class<?> repositoryInterface = getRepositoryInterface();
167168

168169
return new DefaultQueryMethods(Streamable.of(Arrays.stream(repositoryInterface.getMethods())
169-
.map(it -> ClassUtils.getMostSpecificMethod(it, repositoryInterface))
170-
.filter(this::isQueryMethodCandidate)
170+
.map(it -> ClassUtils.getMostSpecificMethod(it, repositoryInterface)) //
171+
.filter(this::isQueryMethodCandidate) //
171172
.toList()), calculateHasCustomMethod(repositoryInterface));
172173
}
173174

@@ -187,6 +188,27 @@ private final boolean calculateHasCustomMethod(Class<?> repositoryInterface) {
187188
return false;
188189
}
189190

191+
/**
192+
* Returns where the given type is the {@link Repository} interface.
193+
*
194+
* @param ifc
195+
* @return
196+
*/
197+
private static boolean isGenericRepositoryInterface(Class<?> ifc) {
198+
return Repository.class.equals(ifc);
199+
}
200+
201+
/**
202+
* Returns whether the given type name is a repository interface name.
203+
*
204+
* @param interfaceName
205+
* @return
206+
*/
207+
@Contract("null -> false")
208+
public static boolean isGenericRepositoryInterface(@Nullable String interfaceName) {
209+
return Repository.class.getName().equals(interfaceName);
210+
}
211+
190212
/**
191213
* Information about query methods to allow canonical computation and reuse of that information.
192214
*

src/main/java/org/springframework/data/repository/core/support/QueryExecutionResultHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.springframework.core.convert.ConversionService;
2828
import org.springframework.core.convert.TypeDescriptor;
2929
import org.springframework.core.convert.support.GenericConversionService;
30-
import org.springframework.data.repository.util.ClassUtils;
3130
import org.springframework.data.repository.util.QueryExecutionConverters;
3231
import org.springframework.data.repository.util.ReactiveWrapperConverters;
3332
import org.springframework.data.util.NullableWrapper;
@@ -67,7 +66,8 @@ class QueryExecutionResultHandler {
6766
public static <T> Class<T> loadIfPresent(String type) {
6867

6968
try {
70-
return (Class<T>) org.springframework.util.ClassUtils.forName(type, ClassUtils.class.getClassLoader());
69+
return (Class<T>) org.springframework.util.ClassUtils.forName(type,
70+
QueryExecutionResultHandler.class.getClassLoader());
7171
} catch (ClassNotFoundException | LinkageError e) {
7272
return null;
7373
}

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public void setNamedQueries(@Nullable NamedQueries namedQueries) {
183183

184184
@Override
185185
public void setBeanClassLoader(@Nullable ClassLoader classLoader) {
186-
this.classLoader = classLoader == null ? org.springframework.util.ClassUtils.getDefaultClassLoader() : classLoader;
186+
this.classLoader = classLoader == null ? ClassUtils.getDefaultClassLoader() : classLoader;
187187
this.projectionFactory = createProjectionFactory();
188188
}
189189

@@ -700,7 +700,7 @@ public Object invoke(@SuppressWarnings("null") MethodInvocation invocation) thro
700700
try {
701701
return composition.invoke(invocationMulticaster, method, arguments);
702702
} catch (Exception e) {
703-
org.springframework.data.repository.util.ClassUtils.unwrapReflectionException(e);
703+
org.springframework.util.ReflectionUtils.handleReflectionException(e);
704704
}
705705

706706
throw new IllegalStateException("Should not occur");
@@ -834,25 +834,24 @@ static class RepositoryValidator {
834834

835835
static {
836836

837-
org.springframework.data.repository.util.ClassUtils.ifPresent(
838-
"org.springframework.data.querydsl.QuerydslPredicateExecutor", RepositoryValidator.class.getClassLoader(),
839-
it -> {
837+
org.springframework.data.util.ClassUtils.ifPresent("org.springframework.data.querydsl.QuerydslPredicateExecutor",
838+
RepositoryValidator.class.getClassLoader(), it -> {
840839
WELL_KNOWN_EXECUTORS.put(it, "Querydsl");
841840
});
842841

843-
org.springframework.data.repository.util.ClassUtils.ifPresent(
842+
org.springframework.data.util.ClassUtils.ifPresent(
844843
"org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor",
845844
RepositoryValidator.class.getClassLoader(), it -> {
846845
WELL_KNOWN_EXECUTORS.put(it, "Reactive Querydsl");
847846
});
848847

849-
org.springframework.data.repository.util.ClassUtils.ifPresent(
848+
org.springframework.data.util.ClassUtils.ifPresent(
850849
"org.springframework.data.repository.query.QueryByExampleExecutor",
851850
RepositoryValidator.class.getClassLoader(), it -> {
852851
WELL_KNOWN_EXECUTORS.put(it, "Query by Example");
853852
});
854853

855-
org.springframework.data.repository.util.ClassUtils.ifPresent(
854+
org.springframework.data.util.ClassUtils.ifPresent(
856855
"org.springframework.data.repository.query.ReactiveQueryByExampleExecutor",
857856
RepositoryValidator.class.getClassLoader(), it -> {
858857
WELL_KNOWN_EXECUTORS.put(it, "Reactive Query by Example");

src/main/java/org/springframework/data/repository/query/Parameter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
import org.springframework.data.domain.Pageable;
3131
import org.springframework.data.domain.ScrollPosition;
3232
import org.springframework.data.domain.Sort;
33-
import org.springframework.data.repository.util.ClassUtils;
3433
import org.springframework.data.repository.util.QueryExecutionConverters;
3534
import org.springframework.data.repository.util.ReactiveWrapperConverters;
35+
import org.springframework.data.util.ClassUtils;
3636
import org.springframework.data.util.Lazy;
3737
import org.springframework.data.util.TypeInformation;
3838
import org.springframework.util.Assert;

src/main/java/org/springframework/data/repository/query/QueryMethod.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
*/
1616
package org.springframework.data.repository.query;
1717

18-
import static org.springframework.data.repository.util.ClassUtils.*;
19-
2018
import java.lang.reflect.Method;
2119
import java.util.Collections;
2220
import java.util.Set;
@@ -38,6 +36,7 @@
3836
import org.springframework.data.util.Lazy;
3937
import org.springframework.data.util.NullableWrapperConverters;
4038
import org.springframework.data.util.ReactiveWrappers;
39+
import org.springframework.data.util.ReflectionUtils;
4140
import org.springframework.data.util.TypeInformation;
4241
import org.springframework.util.Assert;
4342

@@ -77,7 +76,9 @@ public QueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory
7776
Assert.notNull(factory, "ProjectionFactory must not be null");
7877

7978
Parameters.TYPES.stream() //
80-
.filter(type -> getNumberOfOccurrences(method, type) > 1).findFirst().ifPresent(type -> {
79+
.filter(type -> ReflectionUtils.getParameterCount(method, type::equals) > 1) //
80+
.findFirst() //
81+
.ifPresent(type -> {
8182
throw new IllegalStateException(String.format(
8283
"Method must have only one argument of type %s; Offending method: %s", type.getSimpleName(), method));
8384
});
@@ -107,19 +108,19 @@ private void validate() {
107108

108109
QueryMethodValidator.validate(method);
109110

110-
if (hasParameterOfType(method, Pageable.class)) {
111+
if (ReflectionUtils.hasParameterOfType(method, Pageable.class)) {
111112

112113
if (!isStreamQuery()) {
113114
assertReturnTypeAssignable(method, QueryExecutionConverters.getAllowedPageableTypes());
114115
}
115116

116-
if (hasParameterOfType(method, Sort.class)) {
117+
if (ReflectionUtils.hasParameterOfType(method, Sort.class)) {
117118
throw new IllegalStateException(String.format("Method must not have Pageable *and* Sort parameters. "
118119
+ "Use sorting capabilities on Pageable instead; Offending method: %s", method));
119120
}
120121
}
121122

122-
if (hasParameterOfType(method, ScrollPosition.class)) {
123+
if (ReflectionUtils.hasParameterOfType(method, ScrollPosition.class)) {
123124
assertReturnTypeAssignable(method, Collections.singleton(Window.class));
124125
}
125126

@@ -374,11 +375,12 @@ static void validate(Method method) {
374375

375376
static Predicate<Method> pageableCannotHaveSortOrLimit = (method) -> {
376377

377-
if (!hasParameterAssignableToType(method, Pageable.class)) {
378+
if (!ReflectionUtils.hasParameterAssignableToType(method, Pageable.class)) {
378379
return true;
379380
}
380381

381-
if (hasParameterAssignableToType(method, Sort.class) || hasParameterAssignableToType(method, Limit.class)) {
382+
if (ReflectionUtils.hasParameterAssignableToType(method, Sort.class)
383+
|| ReflectionUtils.hasParameterAssignableToType(method, Limit.class)) {
382384
return false;
383385
}
384386

0 commit comments

Comments
 (0)