Browse Source

DATACMNS-1102 - Avoid superfluous recreation of ConversionService for projections.

For repository query methods with a dynamic projection parameter, the ResultProcessor is recreated with the type handed to the method. This results in recreation of the ProjectingConverter, which previously recreated a DefaultConversionService instance (for fallback conversions), which is rather expensive due to the reflection lookups checking for the presence of libraries on the classpath.

This is now avoided by using copying methods that reuse the initially created DefaultConversionService.
pull/347/head
Oliver Gierke 9 years ago
parent
commit
899913cdf6
  1. 36
      src/main/java/org/springframework/data/repository/query/ResultProcessor.java

36
src/main/java/org/springframework/data/repository/query/ResultProcessor.java

@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
*/
package org.springframework.data.repository.query;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@ -43,6 +45,7 @@ import org.springframework.util.Assert; @@ -43,6 +45,7 @@ import org.springframework.util.Assert;
* @author John Blum
* @since 1.12
*/
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class ResultProcessor {
private final QueryMethod method;
@ -94,7 +97,7 @@ public class ResultProcessor { @@ -94,7 +97,7 @@ public class ResultProcessor {
Class<?> projectionType = accessor.getDynamicProjection();
return projectionType == null ? this : new ResultProcessor(method, factory, projectionType);
return projectionType == null ? this : withType(projectionType);
}
/**
@ -159,6 +162,12 @@ public class ResultProcessor { @@ -159,6 +162,12 @@ public class ResultProcessor {
return (T) converter.convert(source);
}
private ResultProcessor withType(Class<?> type) {
ReturnedType returnedType = ReturnedType.of(type, method.getDomainClass(), factory);
return new ResultProcessor(method, converter.withType(returnedType), factory, returnedType);
}
/**
* Creates a new {@link Collection} for the given source. Will try to create an instance of the source collection's
* type first falling back to creating an approximate collection if the former fails.
@ -238,7 +247,30 @@ public class ResultProcessor { @@ -238,7 +247,30 @@ public class ResultProcessor {
private final @NonNull ReturnedType type;
private final @NonNull ProjectionFactory factory;
private final ConversionService conversionService = new DefaultConversionService();
private final @NonNull ConversionService conversionService;
/**
* Creates a new {@link ProjectingConverter} for the given {@link ReturnedType} and {@link ProjectionFactory}.
*
* @param type must not be {@literal null}.
* @param factory must not be {@literal null}.
*/
ProjectingConverter(ReturnedType type, ProjectionFactory factory) {
this(type, factory, new DefaultConversionService());
}
/**
* Creates a new {@link ProjectingConverter} for the given {@link ReturnedType}.
*
* @param type must not be {@literal null}.
* @return
*/
ProjectingConverter withType(ReturnedType type) {
Assert.notNull(type, "ReturnedType must not be null!");
return new ProjectingConverter(type, factory, conversionService);
}
/*
* (non-Javadoc)

Loading…
Cancel
Save