From 541ef648f1850be7e7af08294c842fab3c0bcc71 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 7 Aug 2013 14:39:37 +0200 Subject: [PATCH] DATACMNS-356 - Parameters now uses DefaultParameterNameDiscoverer if present. We now leniently try to lookup DefaultParameterNameDiscoverer and create an instance of it to make use of Spring 4's improved parameter name capabilities on Java 8. We fall back on a LocalVariableTableParameterNameDiscoverer if on Spring versions prior to 4. --- .../data/repository/query/Parameters.java | 5 ++-- .../data/util/ReflectionUtils.java | 23 ++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/repository/query/Parameters.java b/src/main/java/org/springframework/data/repository/query/Parameters.java index a889c45a0..3c8172e65 100644 --- a/src/main/java/org/springframework/data/repository/query/Parameters.java +++ b/src/main/java/org/springframework/data/repository/query/Parameters.java @@ -28,6 +28,7 @@ import org.springframework.core.MethodParameter; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.util.ReflectionUtils; import org.springframework.util.Assert; /** @@ -44,12 +45,12 @@ public abstract class Parameters, T extends Parameter private static final String ALL_OR_NOTHING = String.format("Either use @%s " + "on all parameters except %s and %s typed once, or none at all!", Param.class.getSimpleName(), Pageable.class.getSimpleName(), Sort.class.getSimpleName()); + private static final ParameterNameDiscoverer discoverer = ReflectionUtils.createInstanceIfPresent( + "org.springframework.core.DefaultParameterNameDiscoverer", new LocalVariableTableParameterNameDiscoverer()); private final int pageableIndex; private final int sortIndex; - private final List parameters; - private final ParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer(); /** * Creates a new instance of {@link Parameters}. diff --git a/src/main/java/org/springframework/data/util/ReflectionUtils.java b/src/main/java/org/springframework/data/util/ReflectionUtils.java index 1e3c916b0..9ebd35634 100644 --- a/src/main/java/org/springframework/data/util/ReflectionUtils.java +++ b/src/main/java/org/springframework/data/util/ReflectionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 the original author or authors. + * Copyright 2012-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,10 @@ package org.springframework.data.util; import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import org.springframework.beans.BeanUtils; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils.FieldFilter; /** @@ -30,6 +32,25 @@ import org.springframework.util.ReflectionUtils.FieldFilter; */ public class ReflectionUtils { + /** + * Creates an instance of the class with the given fully qualified name or returns the given default instance if the + * class cannot be loaded or instantiated. + * + * @param classname the fully qualified class name to create an instance for. + * @param defaultInstance the instance to fall back to in case the given class cannot be loaded or instantiated. + * @return + */ + @SuppressWarnings("unchecked") + public static T createInstanceIfPresent(String classname, T defaultInstance) { + + try { + Class type = ClassUtils.getDefaultClassLoader().loadClass(classname); + return (T) BeanUtils.instantiateClass(type); + } catch (Exception e) { + return defaultInstance; + } + } + /** * A {@link FieldFilter} that has a description. *