Use AnnotationUtils.findAnnotation(…) instead of AnnotatedElement.isAnnotationPresent(…).

Enable use of meta annotations by leveraging MergedAnnotations.

Closes #2500
This commit is contained in:
XenoAmess
2021-11-23 04:45:56 +08:00
committed by Mark Paluch
parent 8bd81a796d
commit ca723d11c7
7 changed files with 33 additions and 14 deletions

View File

@@ -34,6 +34,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.core.GenericTypeResolver; import org.springframework.core.GenericTypeResolver;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.core.convert.converter.ConverterRegistry;
@@ -42,6 +43,7 @@ import org.springframework.core.convert.converter.GenericConverter.ConvertiblePa
import org.springframework.core.convert.support.GenericConversionService; import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.convert.ConverterBuilder.ConverterAware; import org.springframework.data.convert.ConverterBuilder.ConverterAware;
import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.repository.RepositoryDefinition;
import org.springframework.data.util.Streamable; import org.springframework.data.util.Streamable;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@@ -57,6 +59,7 @@ import org.springframework.util.ObjectUtils;
* @author Thomas Darimont * @author Thomas Darimont
* @author Christoph Strobl * @author Christoph Strobl
* @author Mark Paluch * @author Mark Paluch
* @author Xeno Amess
* @since 2.0 * @since 2.0
*/ */
public class CustomConversions { public class CustomConversions {
@@ -757,8 +760,8 @@ public class CustomConversions {
Assert.notNull(converter, "Converter must not be null!"); Assert.notNull(converter, "Converter must not be null!");
Class<?> type = converter.getClass(); Class<?> type = converter.getClass();
boolean isWriting = type.isAnnotationPresent(WritingConverter.class); boolean isWriting = AnnotationUtils.findAnnotation(type, WritingConverter.class) != null;
boolean isReading = type.isAnnotationPresent(ReadingConverter.class); boolean isReading = AnnotationUtils.findAnnotation(type, ReadingConverter.class) != null;
if (converter instanceof ConverterAware) { if (converter instanceof ConverterAware) {

View File

@@ -23,8 +23,10 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.util.Lazy; import org.springframework.data.util.Lazy;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@@ -42,6 +44,7 @@ import org.springframework.util.StringUtils;
* @author Christoph Strobl * @author Christoph Strobl
* @author Mark Paluch * @author Mark Paluch
* @author Myeonghyeon Lee * @author Myeonghyeon Lee
* @author Xeno Amess
*/ */
public class PreferredConstructor<T, P extends PersistentProperty<P>> { public class PreferredConstructor<T, P extends PersistentProperty<P>> {
@@ -110,7 +113,7 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> {
* @return * @return
*/ */
public boolean isExplicitlyAnnotated() { public boolean isExplicitlyAnnotated() {
return constructor.isAnnotationPresent(PersistenceConstructor.class); return AnnotationUtils.findAnnotation(constructor, PersistenceConstructor.class) != null;
} }
/** /**

View File

@@ -26,8 +26,12 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import javax.inject.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentProperty;
@@ -46,6 +50,7 @@ import org.springframework.util.Assert;
* @author Christoph Strobl * @author Christoph Strobl
* @author Roman Rodov * @author Roman Rodov
* @author Mark Paluch * @author Mark Paluch
* @author Xeno Amess
*/ */
public interface PreferredConstructorDiscoverer<T, P extends PersistentProperty<P>> { public interface PreferredConstructorDiscoverer<T, P extends PersistentProperty<P>> {
@@ -115,7 +120,7 @@ public interface PreferredConstructorDiscoverer<T, P extends PersistentProperty<
continue; continue;
} }
if (candidate.isAnnotationPresent(PersistenceConstructor.class)) { if (AnnotationUtils.findAnnotation(candidate, PersistenceConstructor.class) != null) {
return buildPreferredConstructor(candidate, type, entity); return buildPreferredConstructor(candidate, type, entity);
} }
@@ -153,7 +158,7 @@ public interface PreferredConstructorDiscoverer<T, P extends PersistentProperty<
return Arrays.stream(rawOwningType.getDeclaredConstructors()) // return Arrays.stream(rawOwningType.getDeclaredConstructors()) //
.filter(it -> !it.isSynthetic()) // Synthetic constructors should not be considered .filter(it -> !it.isSynthetic()) // Synthetic constructors should not be considered
.filter(it -> it.isAnnotationPresent(PersistenceConstructor.class)) // Explicitly defined constructor trumps .filter(it -> AnnotationUtils.findAnnotation(it, PersistenceConstructor.class) != null) // Explicitly defined constructor trumps
// all // all
.map(it -> buildPreferredConstructor(it, type, entity)) // .map(it -> buildPreferredConstructor(it, type, entity)) //
.findFirst() // .findFirst() //

View File

@@ -27,6 +27,8 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.context.expression.MapAccessor; import org.springframework.context.expression.MapAccessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.expression.EvaluationContext; import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression; import org.springframework.expression.Expression;
import org.springframework.expression.ParserContext; import org.springframework.expression.ParserContext;
@@ -45,6 +47,7 @@ import org.springframework.util.StringUtils;
* @author Oliver Gierke * @author Oliver Gierke
* @author Thomas Darimont * @author Thomas Darimont
* @author Christoph Strobl * @author Christoph Strobl
* @author Xeno Amess
* @see 1.10 * @see 1.10
*/ */
class SpelEvaluatingMethodInterceptor implements MethodInterceptor { class SpelEvaluatingMethodInterceptor implements MethodInterceptor {
@@ -108,12 +111,11 @@ class SpelEvaluatingMethodInterceptor implements MethodInterceptor {
for (Method method : targetInterface.getMethods()) { for (Method method : targetInterface.getMethods()) {
if (!method.isAnnotationPresent(Value.class)) { Value value = AnnotationUtils.findAnnotation(method, Value.class);
if (value == null) {
continue; continue;
} }
Value value = method.getAnnotation(Value.class);
if (!StringUtils.hasText(value.value())) { if (!StringUtils.hasText(value.value())) {
throw new IllegalStateException(String.format("@Value annotation on %s contains empty expression!", method)); throw new IllegalStateException(String.format("@Value annotation on %s contains empty expression!", method));
} }

View File

@@ -40,7 +40,9 @@ import javax.enterprise.inject.spi.PassivationCapable;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.log.LogMessage; import org.springframework.core.log.LogMessage;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.repository.config.CustomRepositoryImplementationDetector; import org.springframework.data.repository.config.CustomRepositoryImplementationDetector;
import org.springframework.data.repository.config.RepositoryFragmentConfiguration; import org.springframework.data.repository.config.RepositoryFragmentConfiguration;
import org.springframework.data.repository.core.support.RepositoryComposition.RepositoryFragments; import org.springframework.data.repository.core.support.RepositoryComposition.RepositoryFragments;
@@ -61,6 +63,7 @@ import org.springframework.util.StringUtils;
* @author Jens Schauder * @author Jens Schauder
* @author Christoph Strobl * @author Christoph Strobl
* @author Ariel Carrera * @author Ariel Carrera
* @author Xeno Amess
*/ */
public abstract class CdiRepositoryBean<T> implements Bean<T>, PassivationCapable { public abstract class CdiRepositoryBean<T> implements Bean<T>, PassivationCapable {
@@ -261,7 +264,7 @@ public abstract class CdiRepositoryBean<T> implements Bean<T>, PassivationCapabl
return Arrays.stream(repositoryType.getAnnotations())// return Arrays.stream(repositoryType.getAnnotations())//
.map(Annotation::annotationType)// .map(Annotation::annotationType)//
.filter(it -> it.isAnnotationPresent(Stereotype.class))// .filter(it -> AnnotationUtils.findAnnotation(it, Stereotype.class) != null)//
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@@ -278,7 +281,7 @@ public abstract class CdiRepositoryBean<T> implements Bean<T>, PassivationCapabl
* @see javax.enterprise.inject.spi.Bean#isAlternative() * @see javax.enterprise.inject.spi.Bean#isAlternative()
*/ */
public boolean isAlternative() { public boolean isAlternative() {
return repositoryType.isAnnotationPresent(Alternative.class); return AnnotationUtils.findAnnotation(repositoryType, Alternative.class) != null;
} }
/* /*

View File

@@ -49,6 +49,7 @@ import org.springframework.data.repository.config.CustomRepositoryImplementation
* @author Oliver Gierke * @author Oliver Gierke
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl * @author Christoph Strobl
* @author Xeno Amess
*/ */
public abstract class CdiRepositoryExtensionSupport implements Extension { public abstract class CdiRepositoryExtensionSupport implements Extension {
@@ -98,8 +99,8 @@ public abstract class CdiRepositoryExtensionSupport implements Extension {
boolean isInterface = type.isInterface(); boolean isInterface = type.isInterface();
boolean extendsRepository = Repository.class.isAssignableFrom(type); boolean extendsRepository = Repository.class.isAssignableFrom(type);
boolean isAnnotated = type.isAnnotationPresent(RepositoryDefinition.class); boolean isAnnotated = AnnotationUtils.findAnnotation(type, RepositoryDefinition.class) != null;
boolean excludedByAnnotation = type.isAnnotationPresent(NoRepositoryBean.class); boolean excludedByAnnotation = AnnotationUtils.findAnnotation(type, NoRepositoryBean.class) != null;
return isInterface && (extendsRepository || isAnnotated) && !excludedByAnnotation; return isInterface && (extendsRepository || isAnnotated) && !excludedByAnnotation;
} }
@@ -113,7 +114,7 @@ public abstract class CdiRepositoryExtensionSupport implements Extension {
Annotation[] annotations = type.getAnnotations(); Annotation[] annotations = type.getAnnotations();
for (Annotation annotation : annotations) { for (Annotation annotation : annotations) {
Class<? extends Annotation> annotationType = annotation.annotationType(); Class<? extends Annotation> annotationType = annotation.annotationType();
if (annotationType.isAnnotationPresent(Qualifier.class)) { if (AnnotationUtils.findAnnotation(annotationType, Qualifier.class) != null) {
qualifiers.add(annotation); qualifiers.add(annotation);
} }
} }

View File

@@ -15,6 +15,7 @@
*/ */
package org.springframework.data.repository.core.support; package org.springframework.data.repository.core.support;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.repository.RepositoryDefinition; import org.springframework.data.repository.RepositoryDefinition;
import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@@ -25,6 +26,7 @@ import org.springframework.util.Assert;
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Thomas Darimont * @author Thomas Darimont
* @author Xeno Amess
*/ */
public class AnnotationRepositoryMetadata extends AbstractRepositoryMetadata { public class AnnotationRepositoryMetadata extends AbstractRepositoryMetadata {
@@ -44,7 +46,7 @@ public class AnnotationRepositoryMetadata extends AbstractRepositoryMetadata {
super(repositoryInterface); super(repositoryInterface);
Assert.isTrue(repositoryInterface.isAnnotationPresent(RepositoryDefinition.class), Assert.isTrue(AnnotationUtils.findAnnotation(repositoryInterface, RepositoryDefinition.class) != null,
String.format(NO_ANNOTATION_FOUND, repositoryInterface.getName())); String.format(NO_ANNOTATION_FOUND, repositoryInterface.getName()));
this.idType = resolveIdType(repositoryInterface); this.idType = resolveIdType(repositoryInterface);