下面列出了怎么用java.lang.reflect.AnnotatedElement的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Given a single-argument method whose parameter is a {@link Collection}, use
* the method's generic type information to determine the collection element
* type and store it as the ITEM_CLASS_NAME attribute of the given Element.
*
* @param method
* the setter method
* @param paramElt
* the PARAMETER element
*/
private void determineCollectionElementType(AnnotatedElement method,
Type paramType, Element paramElt) {
if(paramElt.getAttributeValue("ITEM_CLASS_NAME") == null) {
Class<?> elementType;
CreoleParameter paramAnnot = method.getAnnotation(CreoleParameter.class);
if(paramAnnot != null
&& paramAnnot.collectionElementType() != CreoleParameter.NoElementType.class) {
elementType = paramAnnot.collectionElementType();
} else {
elementType = findCollectionElementType(paramType);
}
if(elementType != null) {
paramElt.setAttribute("ITEM_CLASS_NAME", elementType.getName());
}
}
}
/**
* Validates the specified {@link CacheOperation}.
* <p>Throws an {@link IllegalStateException} if the state of the operation is
* invalid. As there might be multiple sources for default values, this ensure
* that the operation is in a proper state before being returned.
* @param ae the annotated element of the cache operation
* @param operation the {@link CacheOperation} to validate
*/
private void validateCacheOperation(AnnotatedElement ae, CacheOperation operation) {
if (StringUtils.hasText(operation.getKey()) && StringUtils.hasText(operation.getKeyGenerator())) {
throw new IllegalStateException("Invalid cache annotation configuration on '" +
ae.toString() + "'. Both 'key' and 'keyGenerator' attributes have been set. " +
"These attributes are mutually exclusive: either set the SpEL expression used to" +
"compute the key at runtime or set the name of the KeyGenerator bean to use.");
}
if (StringUtils.hasText(operation.getCacheManager()) && StringUtils.hasText(operation.getCacheResolver())) {
throw new IllegalStateException("Invalid cache annotation configuration on '" +
ae.toString() + "'. Both 'cacheManager' and 'cacheResolver' attributes have been set. " +
"These attributes are mutually exclusive: the cache manager is used to configure a" +
"default cache resolver if none is set. If a cache resolver is set, the cache manager" +
"won't be used.");
}
}
private boolean matchesActiveSpringProfile(AnnotatedElement element) {
if (!ClassUtils.isPresent("org.springframework.context.annotation.Profile", null)) {
return true;
}
if (!element.isAnnotationPresent(Profile.class)) {
return true; // no-profiled changeset always matches
}
List<String> profiles = asList(element.getAnnotation(Profile.class).value());
for (String profile : profiles) {
if (profile != null && profile.length() > 0 && profile.charAt(0) == '!') {
if (!activeProfiles.contains(profile.substring(1))) {
return true;
}
} else if (activeProfiles.contains(profile)) {
return true;
}
}
return false;
}
/**
* @return The list of annotation->owningElement pairs from the given 2-dimensional array that match the given
* desiredAnnotationClass - note that if desiredAnnotationClassIsMultiValueConstraint is true then each matching
* annotation will be exploded via {@link #explodeAnnotationToManyConstraintsIfMultiValue(java.lang.annotation.Annotation,
* boolean)} before being added to the return list.
*/
private static List<Pair<Annotation, AnnotatedElement>> extractAnnotationsFrom2dArray(
Annotation[][] annotations2dArray, Class<? extends Annotation> desiredAnnotationClass,
boolean desiredAnnotationClassIsMultiValueConstraint, AnnotatedElement owningElement) {
List<Pair<Annotation, AnnotatedElement>> returnList = new ArrayList<>();
for (Annotation[] innerArray : annotations2dArray) {
for (Annotation annotation : innerArray) {
if (annotation.annotationType().equals(desiredAnnotationClass)) {
List<Annotation> annotationsToRegister = explodeAnnotationToManyConstraintsIfMultiValue(
annotation, desiredAnnotationClassIsMultiValueConstraint
);
for (Annotation annotationToRegister : annotationsToRegister) {
returnList.add(Pair.of(annotationToRegister, owningElement));
}
}
}
}
return returnList;
}
/**
* Validates the specified {@link CacheOperation}.
* <p>Throws an {@link IllegalStateException} if the state of the operation is
* invalid. As there might be multiple sources for default values, this ensure
* that the operation is in a proper state before being returned.
* @param ae the annotated element of the cache operation
* @param operation the {@link CacheOperation} to validate
*/
private void validateCacheOperation(AnnotatedElement ae, CacheOperation operation) {
if (StringUtils.hasText(operation.getKey()) && StringUtils.hasText(operation.getKeyGenerator())) {
throw new IllegalStateException("Invalid cache annotation configuration on '" +
ae.toString() + "'. Both 'key' and 'keyGenerator' attributes have been set. " +
"These attributes are mutually exclusive: either set the SpEL expression used to" +
"compute the key at runtime or set the name of the KeyGenerator bean to use.");
}
if (StringUtils.hasText(operation.getCacheManager()) && StringUtils.hasText(operation.getCacheResolver())) {
throw new IllegalStateException("Invalid cache annotation configuration on '" +
ae.toString() + "'. Both 'cacheManager' and 'cacheResolver' attributes have been set. " +
"These attributes are mutually exclusive: the cache manager is used to configure a" +
"default cache resolver if none is set. If a cache resolver is set, the cache manager" +
"won't be used.");
}
}
@Override
public <T extends Annotation> AnnotationInfo getAnnotation(Class<T> metric) {
T annotation = input.getAnnotation(metric);
if (annotation != null) {
return new CDIAnnotationInfoAdapter().convert(annotation);
} else {
// the metric annotation can also be applied via a stereotype, so look for stereotype annotations
for (Annotation stereotypeCandidate : ((AnnotatedElement) input).getAnnotations()) {
if (stereotypeCandidate.annotationType().isAnnotationPresent(Stereotype.class) &&
stereotypeCandidate.annotationType().isAnnotationPresent(metric)) {
return new CDIAnnotationInfoAdapter().convert(stereotypeCandidate.annotationType().getAnnotation(metric));
}
}
return null;
}
}
/** 递归扫描字段 */
private boolean scanField(Class<?> clazz, List<String> visited,
Consumer<AnnotatedElement> consumer) {
// 扫描当前类
for (Field field : clazz.getDeclaredFields()) {
String name = field.getName();
if (!visited.contains(name)) {
if (handle(field, consumer)) {
return true;
}
visited.add(name);
}
}
// 扫描父类
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != null && superClazz != Object.class) {
if (scanField(superClazz, visited, consumer)) {
return true;
}
}
return false;
}
@Override
public boolean canConvert ( final Class<?> from, final Class<?> to, final AnnotatedElement annotatedElement )
{
if ( !to.equals ( String.class ) )
{
return false;
}
if ( from.isAnnotationPresent ( JSON.class ) )
{
return true;
}
if ( annotatedElement != null && annotatedElement.isAnnotationPresent ( JSON.class ) )
{
return true;
}
return false;
}
/**
* Handle the supplied annotation introspection exception.
* <p>If the supplied exception is an {@link AnnotationConfigurationException},
* it will simply be thrown, allowing it to propagate to the caller, and
* nothing will be logged.
* <p>Otherwise, this method logs an introspection failure (in particular
* {@code TypeNotPresentExceptions}) before moving on, assuming nested
* Class values were not resolvable within annotation attributes and
* thereby effectively pretending there were no annotations on the specified
* element.
* @param element the element that we tried to introspect annotations on
* @param ex the exception that we encountered
* @see #rethrowAnnotationConfigurationException
*/
static void handleIntrospectionFailure(AnnotatedElement element, Exception ex) {
rethrowAnnotationConfigurationException(ex);
Log loggerToUse = logger;
if (loggerToUse == null) {
loggerToUse = LogFactory.getLog(AnnotationUtils.class);
logger = loggerToUse;
}
if (element instanceof Class && Annotation.class.isAssignableFrom((Class<?>) element)) {
// Meta-annotation lookup on an annotation type
if (loggerToUse.isDebugEnabled()) {
loggerToUse.debug("Failed to introspect meta-annotations on [" + element + "]: " + ex);
}
}
else {
// Direct annotation lookup on regular Class, Method, Field
if (loggerToUse.isInfoEnabled()) {
loggerToUse.info("Failed to introspect annotations on [" + element + "]: " + ex);
}
}
}
@SuppressWarnings("unchecked")
private void process(AnnotatedElement element) {
if (this.visited.add(element)) {
try {
Annotation[] annotations = (this.declaredMode ? element.getDeclaredAnnotations() : element.getAnnotations());
for (Annotation ann : annotations) {
Class<? extends Annotation> currentAnnotationType = ann.annotationType();
if (ObjectUtils.nullSafeEquals(this.annotationType, currentAnnotationType)) {
this.result.add(synthesizeAnnotation((A) ann, element));
}
else if (ObjectUtils.nullSafeEquals(this.containerAnnotationType, currentAnnotationType)) {
this.result.addAll(getValue(element, ann));
}
else if (!isInJavaLangAnnotationPackage(ann)) {
process(currentAnnotationType);
}
}
}
catch (Exception ex) {
handleIntrospectionFailure(element, ex);
}
}
}
private AlfrescoRunAs parseRunAsAnnotation(AnnotatedElement ae) {
AlfrescoRunAs ann = ae.getAnnotation(AlfrescoRunAs.class);
if (ann == null) {
for (Annotation metaAnn : ae.getAnnotations()) {
ann = metaAnn.annotationType().getAnnotation(AlfrescoRunAs.class);
if (ann != null) {
break;
}
}
}
if (ann != null) {
return parseAnnotation(ann);
} else {
return null;
}
}
public EjbRefElement(Member member, AnnotatedElement ae, PropertyDescriptor pd) {
super(member, pd);
EJB resource = ae.getAnnotation(EJB.class);
String resourceBeanName = resource.beanName();
String resourceName = resource.name();
this.isDefaultName = !StringUtils.hasLength(resourceName);
if (this.isDefaultName) {
resourceName = this.member.getName();
if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
resourceName = Introspector.decapitalize(resourceName.substring(3));
}
}
Class<?> resourceType = resource.beanInterface();
if (resourceType != null && Object.class != resourceType) {
checkResourceType(resourceType);
}
else {
// No resource type specified... check field/method.
resourceType = getResourceType();
}
this.beanName = resourceBeanName;
this.name = resourceName;
this.lookupType = resourceType;
this.mappedName = resource.mappedName();
}
/**
* Utility method for calling an arbitrary method in an annotation.
*
* @param element the element that was annotated, either a class or method
* @param annotation the class of the annotation we're interested in
* @param methodName the name of the method in the annotation we wish
* to call.
* @param defaultValue the value to return if the annotation doesn't
* exist, or we couldn't invoke the method for some reason.
* @return the result of calling the annotation method, or the default.
*/
protected static Object getAnnotationValue(
AnnotatedElement element, Class<? extends Annotation> annotation,
String methodName, Object defaultValue) {
Object ret = defaultValue;
try {
Method m = annotation.getMethod(methodName);
Annotation a = element.getAnnotation(annotation);
ret = m.invoke(a);
} catch (NoSuchMethodException e) {
assert false;
} catch (IllegalAccessException e) {
assert false;
} catch (InvocationTargetException e) {
assert false;
} catch (NullPointerException e) {
assert false;
}
return ret;
}
/**
* Handle the supplied annotation introspection exception.
* <p>If the supplied exception is an {@link AnnotationConfigurationException},
* it will simply be thrown, allowing it to propagate to the caller, and
* nothing will be logged.
* <p>Otherwise, this method logs an introspection failure (in particular
* {@code TypeNotPresentExceptions}) before moving on, assuming nested
* Class values were not resolvable within annotation attributes and
* thereby effectively pretending there were no annotations on the specified
* element.
* @param element the element that we tried to introspect annotations on
* @param ex the exception that we encountered
* @see #rethrowAnnotationConfigurationException
*/
private static void handleIntrospectionFailure(@Nullable AnnotatedElement element, Throwable ex) {
rethrowAnnotationConfigurationException(ex);
IntrospectionFailureLogger logger = IntrospectionFailureLogger.INFO;
boolean meta = false;
if (element instanceof Class && Annotation.class.isAssignableFrom((Class<?>) element)) {
// Meta-annotation or (default) value lookup on an annotation type
logger = IntrospectionFailureLogger.DEBUG;
meta = true;
}
if (logger.isEnabled()) {
String message = meta ?
"Failed to meta-introspect annotation " :
"Failed to introspect annotations on ";
logger.log(message + element + ": " + ex);
}
}
@Override
protected By buildMobileNativeBy() {
AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated();
HowToUseLocators howToUseLocators = annotatedElement.getAnnotation(HowToUseLocators.class);
Optional<HowToUseLocators> howToUseLocatorsOptional = ofNullable(howToUseLocators);
if (isAndroid()) {
return buildMobileBy(howToUseLocatorsOptional.map(HowToUseLocators::androidAutomation).orElse(null),
getBys(AndroidFindBy.class, AndroidFindBys.class, AndroidFindAll.class));
}
if (isIOSXcuit() || isIOS()) {
return buildMobileBy(howToUseLocatorsOptional.map(HowToUseLocators::iOSXCUITAutomation).orElse(null),
getBys(iOSXCUITFindBy.class, iOSXCUITFindBys.class, iOSXCUITFindAll.class));
}
if (isWindows()) {
return buildMobileBy(howToUseLocatorsOptional.map(HowToUseLocators::windowsAutomation).orElse(null),
getBys(WindowsFindBy.class, WindowsFindBys.class, WindowsFindAll.class));
}
return null;
}
private static String getSource(AnnotatedElement element) {
Source source = ReflectionUtil.getAnnotation(element, Source.class);
if (source != null) {
return source.value();
}
return null;
}
public boolean isExtensibleElements(AnnotatedElement element, boolean defaultValue) {
Boolean extensibleElements = (Boolean) getAnnotationValue("extensibleElements",
element,
Boolean.TRUE,
XmlType.class);
if (extensibleElements == null) {
return defaultValue;
}
return extensibleElements;
}
/**
* Determine if the supplied {@link AnnotatedElement} is annotated with a
* <em>composed annotation</em> that is meta-annotated with an annotation
* of the specified {@code annotationName}.
* <p>This method follows <em>get semantics</em> as described in the
* {@linkplain AnnotatedElementUtils class-level javadoc}.
* @param element the annotated element
* @param annotationName the fully qualified class name of the
* meta-annotation type to find
* @return {@code true} if a matching meta-annotation is present
* @see #getMetaAnnotationTypes
*/
public static boolean hasMetaAnnotationTypes(AnnotatedElement element, final String annotationName) {
Assert.notNull(element, "AnnotatedElement must not be null");
Assert.hasLength(annotationName, "annotationName must not be null or empty");
return Boolean.TRUE.equals(searchWithGetSemantics(element, null, annotationName, new SimpleAnnotationProcessor<Boolean>() {
@Override
public Boolean process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) {
boolean found = annotation.annotationType().getName().equals(annotationName);
return (found && metaDepth > 0 ? Boolean.TRUE : CONTINUE);
}
}));
}
<M extends AnnotatedElement & Member> boolean isPresent(M member,
Object propertyValue) {
JsonInclude annotation = member.getAnnotation(JsonInclude.class);
if (annotation != null) {
if (propertyValue == null) {
return false;
}
switch (annotation.value()) {
case NON_ABSENT:
// Technically we should handle Optional and AtomicReference
// but we're not using these types in the api module, so just fall through
case NON_EMPTY:
if (propertyValue instanceof Collection) {
return !((Collection) propertyValue).isEmpty();
} else if (propertyValue instanceof Map) {
return !((Map) propertyValue).isEmpty();
} else if (propertyValue instanceof String) {
return !((String) propertyValue).isEmpty();
} else if (propertyValue instanceof Object[]) {
return ((Object[]) propertyValue).length != 0;
} else if (propertyValue.getClass().isArray()) {
// primitive arrays
try {
return ((int) propertyValue.getClass().getField("length").get(propertyValue)) != 0;
} catch (ReflectiveOperationException e) {
return false;
}
}
}
}
return propertyValue != null;
}
public MetaInfo withAnnotations( AnnotatedElement annotatedElement )
{
for( Annotation annotation : annotatedElement.getAnnotations() )
{
if( !ignored.contains( annotation.annotationType() )
&& get( annotation.annotationType() ) == null )
{
set( annotation );
}
}
return this;
}
private static void checkAnnotations(AnnotatedElement el, AnnotatableWrapper aw) throws Exception {
for (Annotation ann : el.getAnnotations()) {
Annotation wrapper = aw.getAnnotation(ann.annotationType());
assertNotNull(ann.annotationType().getName(), wrapper);
checkAnnotation(ann, wrapper);
}
}
@Override
public AnnotatedElement[] getMembers() {
if (members == null) {
members = super.getMembers();
if (field == null) {
return members;
}
members = new AnnotatedElement[] { members[0], field };
}
return members;
}
public TypeAnnotation(TypeAnnotationTargetInfo targetInfo,
LocationInfo loc,
Annotation annotation,
AnnotatedElement baseDeclaration) {
this.targetInfo = targetInfo;
this.loc = loc;
this.annotation = annotation;
this.baseDeclaration = baseDeclaration;
}
private <E extends AnnotatedElement & Member> String getName(Class<?> clazz, E elem, Object fieldValue) {
com.codahale.metrics.annotation.Metric annotation = elem.getAnnotation(com.codahale.metrics.annotation.Metric.class);
if(annotation == null) {
throw new IllegalArgumentException(elem + " mut be an annotated with " + com.codahale.metrics.annotation.Metric.class);
}
return MetricNameUtil.chooseName(annotation.name(), annotation.absolute(), clazz, elem);
}
public static <T extends Annotation> Optional<T> getAnnotationIfPresent(
AnnotatedElement annotatedElement, Class<T> annotationClass) {
if (annotatedElement.isAnnotationPresent(annotationClass)) {
T annotation = annotatedElement.getAnnotation(annotationClass);
return Optional.of(annotation);
}
return Optional.empty();
}
/**
* Delegates to {@link #createRequestMappingInfo(RequestMapping, RequestCondition)},
* supplying the appropriate custom {@link RequestCondition} depending on whether
* the supplied {@code annotatedElement} is a class or method.
* @see #getCustomTypeCondition(Class)
* @see #getCustomMethodCondition(Method)
*/
@Nullable
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
RequestCondition<?> condition = (element instanceof Class ?
getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
}
/**
* Makes sure that the Reflections helper stuff is working properly and capturing all annotation possibilities (class type, constructor, constructor param, method, method param, and field).
*/
@Test
public void verifyThatTheReflectionsConfigurationIsCapturingAllAnnotationPossibilities() {
List<Pair<Annotation, AnnotatedElement>> annotationOptionsClassAnnotations = getSubAnnotationListForElementsOfOwnerClass(TROLLER.allConstraintAnnotationsMasterList,
DifferentValidationAnnotationOptions.class);
assertThat(annotationOptionsClassAnnotations.size(), is(10));
assertThat(getSubAnnotationListForAnnotationsOfClassType(annotationOptionsClassAnnotations, SomeClassLevelJsr303Annotation.class).size(), is(2));
assertThat(getSubAnnotationListForAnnotationsOfClassType(annotationOptionsClassAnnotations, OtherClassLevelJsr303Annotation.class).size(), is(1));
assertThat(getSubAnnotationListForAnnotationsOfClassType(annotationOptionsClassAnnotations, AssertTrue.class).size(), is(1));
assertThat(getSubAnnotationListForAnnotationsOfClassType(annotationOptionsClassAnnotations, AssertFalse.class).size(), is(1));
assertThat(getSubAnnotationListForAnnotationsOfClassType(annotationOptionsClassAnnotations, NotNull.class).size(), is(2));
assertThat(getSubAnnotationListForAnnotationsOfClassType(annotationOptionsClassAnnotations, Min.class).size(), is(2));
assertThat(getSubAnnotationListForAnnotationsOfClassType(annotationOptionsClassAnnotations, Max.class).size(), is(1));
}
@Test
void shouldRetrieveInjectorWhenPresent() {
Optional<AnnotatedElement> optional = Optional.of(annotatedElement);
when(context.getElement()).thenReturn(optional);
when(store.getOrComputeIfAbsent(any(), any(), eq(Injector.class))).thenReturn(injector);
when(context.getStore(namespace)).thenReturn(store);
assertEquals(injector, InjectorUtils.retrieveInjectorFromStore(context, namespace));
}
public static <A extends Annotation> AnnotatedElement getMethod(Class<?> clazz, Class<A> annotationType) {
if (clazz == null || annotationType == null) {
return null;
}
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.getAnnotation(annotationType) != null) {
return method;
}
}
return null;
}
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
annotation = new Mirror()
.on((AnnotatedElement) InterceptorWithCustomizedAccepts.class)
.reflect().annotation(AcceptsWithAnnotations.class);
}