下面列出了org.springframework.core.annotation.MergedAnnotations#org.springframework.core.annotation.MergedAnnotations.SearchStrategy 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
@Nullable
public org.springframework.jmx.export.metadata.ManagedAttribute getManagedAttribute(Method method) throws InvalidMetadataException {
MergedAnnotation<ManagedAttribute> ann = MergedAnnotations.from(method, SearchStrategy.EXHAUSTIVE)
.get(ManagedAttribute.class).withNonMergedAttributes();
if (!ann.isPresent()) {
return null;
}
org.springframework.jmx.export.metadata.ManagedAttribute bean = new org.springframework.jmx.export.metadata.ManagedAttribute();
Map<String, Object> map = ann.asMap();
MutablePropertyValues pvs = new MutablePropertyValues(map);
pvs.removePropertyValue("defaultValue");
PropertyAccessorFactory.forBeanPropertyAccess(bean).setPropertyValues(pvs);
String defaultValue = (String) map.get("defaultValue");
if (defaultValue.length() > 0) {
bean.setDefaultValue(defaultValue);
}
return bean;
}
private Stream<String> scan(AnnotatedElement element, SearchStrategy searchStrategy) {
List<String> result = new ArrayList<>();
AnnotationsScanner.scan(this, element, searchStrategy,
(criteria, aggregateIndex, source, annotations) -> {
for (Annotation annotation : annotations) {
if (annotation != null) {
String name = ClassUtils.getShortName(
annotation.annotationType());
name = name.substring(name.lastIndexOf(".") + 1);
result.add(aggregateIndex + ":" + name);
}
}
return null;
});
return result.stream();
}
private void testJavaRepeatables(SearchStrategy searchStrategy, Class<?> element,
String[] expected) {
MyRepeatable[] annotations = searchStrategy == SearchStrategy.DIRECT
? element.getDeclaredAnnotationsByType(MyRepeatable.class)
: element.getAnnotationsByType(MyRepeatable.class);
assertThat(Arrays.stream(annotations).map(MyRepeatable::value)).containsExactly(
expected);
}
@Override
@Nullable
public org.springframework.jmx.export.metadata.ManagedResource getManagedResource(Class<?> beanClass) throws InvalidMetadataException {
MergedAnnotation<ManagedResource> ann = MergedAnnotations.from(beanClass, SearchStrategy.EXHAUSTIVE)
.get(ManagedResource.class).withNonMergedAttributes();
if (!ann.isPresent()) {
return null;
}
Class<?> declaringClass = (Class<?>) ann.getSource();
Class<?> target = (declaringClass != null && !declaringClass.isInterface() ? declaringClass : beanClass);
if (!Modifier.isPublic(target.getModifiers())) {
throw new InvalidMetadataException("@ManagedResource class '" + target.getName() + "' must be public");
}
org.springframework.jmx.export.metadata.ManagedResource bean = new org.springframework.jmx.export.metadata.ManagedResource();
Map<String, Object> map = ann.asMap();
List<PropertyValue> list = new ArrayList<>(map.size());
map.forEach((attrName, attrValue) -> {
if (!"value".equals(attrName)) {
Object value = attrValue;
if (this.embeddedValueResolver != null && value instanceof String) {
value = this.embeddedValueResolver.resolveStringValue((String) value);
}
list.add(new PropertyValue(attrName, value));
}
});
PropertyAccessorFactory.forBeanPropertyAccess(bean).setPropertyValues(new MutablePropertyValues(list));
return bean;
}
@Test
public void getFromMethodWithMetaAnnotationOnRoot() throws Exception {
Method method = Leaf.class.getMethod("metaAnnotatedOnRoot");
assertThat(method.getAnnotation(Order.class)).isNull();
assertThat(MergedAnnotations.from(method).get(Order.class).getDepth()).isEqualTo(
1);
assertThat(MergedAnnotations.from(method, SearchStrategy.EXHAUSTIVE).get(
Order.class).getDepth()).isEqualTo(1);
}
@Test
public void exhaustiveWhenComposedOnClassReturnsAnnotations() {
Set<PeteRepeat> annotations = getAnnotations(null, PeteRepeat.class,
SearchStrategy.EXHAUSTIVE, ComposedRepeatableClass.class);
assertThat(annotations.stream().map(PeteRepeat::value)).containsExactly("A", "B",
"C");
}
@Test
public void exhaustiveStrategyOnMethodWithGenericParameterOverrideScansAnnotations()
throws Exception {
Method source = ReflectionUtils.findMethod(GenericOverride.class, "method",
String.class);
assertThat(scan(source, SearchStrategy.EXHAUSTIVE)).containsExactly(
"0:TestAnnotation1", "1:TestAnnotation2");
}
@Test
public void getRepeatableDeclaredOnSuperclass() {
Class<?> element = SubMyRepeatableClass.class;
String[] expectedValuesJava = { "A", "B", "C" };
String[] expectedValuesSpring = { "A", "B", "C", "meta1" };
testRepeatables(SearchStrategy.SUPERCLASS, element, expectedValuesJava,
expectedValuesSpring);
}
@Test
public void getFromMethodWithMethodAnnotationOnLeaf() throws Exception {
Method method = Leaf.class.getMethod("annotatedOnLeaf");
assertThat(method.getAnnotation(Order.class)).isNotNull();
assertThat(MergedAnnotations.from(method).get(Order.class).getDepth()).isEqualTo(
0);
assertThat(MergedAnnotations.from(method, SearchStrategy.EXHAUSTIVE).get(
Order.class).getDepth()).isEqualTo(0);
}
@Test
public void inheritedAnnotationsWhenWhenNonArrayValueAttributeThrowsException() {
assertThatAnnotationConfigurationException().isThrownBy(() ->
getAnnotations(ContainerWithNonArrayValueAttribute.class, InvalidRepeatable.class,
SearchStrategy.INHERITED_ANNOTATIONS, getClass()))
.satisfies(this::nonArrayValueAttributeRequirements);
}
@Test
public void directStrategyOnBridgeMethodScansAnnotations() throws Exception {
Method source = BridgedMethod.class.getDeclaredMethod("method", Object.class);
assertThat(source.isBridge()).isTrue();
assertThat(scan(source, SearchStrategy.DIRECT)).containsExactly(
"0:TestAnnotation1");
}
@Test
public void exhaustiveStrategyOnBridgeMethodScansAnnotations() throws Exception {
Method source = BridgedMethod.class.getDeclaredMethod("method", Object.class);
assertThat(source.isBridge()).isTrue();
assertThat(scan(source, SearchStrategy.EXHAUSTIVE)).containsExactly(
"0:TestAnnotation1", "1:TestAnnotation2");
}
@Test
public void getSuperClassForAllScenarios() {
// no class-level annotation
assertThat(MergedAnnotations.from(NonAnnotatedInterface.class,
SearchStrategy.SUPERCLASS).get(
Transactional.class).getSource()).isNull();
assertThat(MergedAnnotations.from(NonAnnotatedClass.class,
SearchStrategy.SUPERCLASS).get(
Transactional.class).getSource()).isNull();
// inherited class-level annotation; note: @Transactional is inherited
assertThat(MergedAnnotations.from(InheritedAnnotationInterface.class,
SearchStrategy.SUPERCLASS).get(
Transactional.class).getSource()).isEqualTo(
InheritedAnnotationInterface.class);
assertThat(MergedAnnotations.from(SubInheritedAnnotationInterface.class,
SearchStrategy.SUPERCLASS).get(
Transactional.class).getSource()).isNull();
assertThat(MergedAnnotations.from(InheritedAnnotationClass.class,
SearchStrategy.SUPERCLASS).get(
Transactional.class).getSource()).isEqualTo(
InheritedAnnotationClass.class);
assertThat(MergedAnnotations.from(SubInheritedAnnotationClass.class,
SearchStrategy.SUPERCLASS).get(
Transactional.class).getSource()).isEqualTo(
InheritedAnnotationClass.class);
// non-inherited class-level annotation; note: @Order is not inherited,
// but we should still find it on classes.
assertThat(MergedAnnotations.from(NonInheritedAnnotationInterface.class,
SearchStrategy.SUPERCLASS).get(Order.class).getSource()).isEqualTo(
NonInheritedAnnotationInterface.class);
assertThat(MergedAnnotations.from(SubNonInheritedAnnotationInterface.class,
SearchStrategy.SUPERCLASS).get(Order.class).getSource()).isNull();
assertThat(MergedAnnotations.from(NonInheritedAnnotationClass.class,
SearchStrategy.SUPERCLASS).get(Order.class).getSource()).isEqualTo(
NonInheritedAnnotationClass.class);
assertThat(MergedAnnotations.from(SubNonInheritedAnnotationClass.class,
SearchStrategy.SUPERCLASS).get(Order.class).getSource()).isEqualTo(
NonInheritedAnnotationClass.class);
}
@Test
public void getFromMethodWithMetaMetaAnnotationOnLeaf() throws Exception {
Method method = Leaf.class.getMethod("metaMetaAnnotatedOnLeaf");
assertThat(method.getAnnotation(Component.class)).isNull();
assertThat(
MergedAnnotations.from(method).get(Component.class).getDepth()).isEqualTo(
2);
assertThat(MergedAnnotations.from(method, SearchStrategy.EXHAUSTIVE).get(
Component.class).getDepth()).isEqualTo(2);
}
@Test
public void getAggregateIndexForAllScenarios() {
// no class-level annotation
assertThat(MergedAnnotations.from(NonAnnotatedInterface.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Transactional.class).getAggregateIndex()).isEqualTo(-1);
assertThat(MergedAnnotations.from(NonAnnotatedClass.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Transactional.class).getAggregateIndex()).isEqualTo(-1);
// inherited class-level annotation; note: @Transactional is inherited
assertThat(MergedAnnotations.from(InheritedAnnotationInterface.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Transactional.class).getAggregateIndex()).isEqualTo(0);
// Since we're not traversing interface hierarchies the following,
// though perhaps
// counter intuitive, must be false:
assertThat(MergedAnnotations.from(SubInheritedAnnotationInterface.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Transactional.class).getAggregateIndex()).isEqualTo(-1);
assertThat(MergedAnnotations.from(InheritedAnnotationClass.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Transactional.class).getAggregateIndex()).isEqualTo(0);
assertThat(MergedAnnotations.from(SubInheritedAnnotationClass.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Transactional.class).getAggregateIndex()).isEqualTo(1);
// non-inherited class-level annotation; note: @Order is not inherited
assertThat(MergedAnnotations.from(NonInheritedAnnotationInterface.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Order.class).getAggregateIndex()).isEqualTo(0);
assertThat(MergedAnnotations.from(SubNonInheritedAnnotationInterface.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Order.class).getAggregateIndex()).isEqualTo(-1);
assertThat(MergedAnnotations.from(NonInheritedAnnotationClass.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Order.class).getAggregateIndex()).isEqualTo(0);
assertThat(MergedAnnotations.from(SubNonInheritedAnnotationClass.class,
SearchStrategy.INHERITED_ANNOTATIONS).get(
Order.class).getAggregateIndex()).isEqualTo(-1);
}
@Nullable
private static <C, R> R process(C context, AnnotatedElement source,
SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor,
@Nullable BiPredicate<C, Class<?>> classFilter) {
if (source instanceof Class) {
return processClass(context, (Class<?>) source, searchStrategy, processor, classFilter);
}
if (source instanceof Method) {
return processMethod(context, (Method) source, searchStrategy, processor, classFilter);
}
return processElement(context, source, processor, classFilter);
}
@Test
public void exhaustiveWhenWhenNonArrayValueAttributeThrowsException() {
assertThatAnnotationConfigurationException().isThrownBy(() ->
getAnnotations(ContainerWithNonArrayValueAttribute.class, InvalidRepeatable.class,
SearchStrategy.EXHAUSTIVE, getClass()))
.satisfies(this::nonArrayValueAttributeRequirements);
}
@Test
public void exhaustiveWhenComposedContainerForRepeatableOnClassReturnsAnnotations() {
Set<PeteRepeat> annotations = getAnnotations(null, PeteRepeat.class,
SearchStrategy.EXHAUSTIVE, ComposedContainerClass.class);
assertThat(annotations.stream().map(PeteRepeat::value)).containsExactly("A", "B",
"C");
}
static boolean isKnownEmpty(AnnotatedElement source, SearchStrategy searchStrategy) {
if (hasPlainJavaAnnotationsOnly(source)) {
return true;
}
if (searchStrategy == SearchStrategy.DIRECT || isWithoutHierarchy(source)) {
if (source instanceof Method && ((Method) source).isBridge()) {
return false;
}
return getDeclaredAnnotations(source, false).length == 0;
}
return false;
}
@Nullable
private Integer findOrderFromAnnotation(Object obj) {
AnnotatedElement element = (obj instanceof AnnotatedElement ? (AnnotatedElement) obj : obj.getClass());
MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.EXHAUSTIVE);
Integer order = OrderUtils.getOrderFromAnnotations(element, annotations);
if (order == null && obj instanceof DecoratingProxy) {
return findOrderFromAnnotation(((DecoratingProxy) obj).getDecoratedClass());
}
return order;
}
@Test
public void getDirectFromClassWithSubNonInheritedAnnotationInterface() {
MergedAnnotation<?> annotation = MergedAnnotations.from(
SubNonInheritedAnnotationInterface.class, SearchStrategy.EXHAUSTIVE).get(
Order.class);
assertThat(annotation.getAggregateIndex()).isEqualTo(1);
}
@Test
public void getDirectRepeatablesDeclaredOnSuperclass() {
Class<?> element = SubMyRepeatableClass.class;
String[] expectedValuesJava = {};
String[] expectedValuesSpring = {};
testRepeatables(SearchStrategy.DIRECT, element, expectedValuesJava,
expectedValuesSpring);
}
@Test
public void scanWhenProcessorReturnsFromDoWithAnnotationsExitsEarly() {
List<Integer> indexes = new ArrayList<>();
String result = AnnotationsScanner.scan(this, WithSingleSuperclass.class,
SearchStrategy.EXHAUSTIVE,
(context, aggregateIndex, source, annotations) -> {
indexes.add(aggregateIndex);
return "";
});
assertThat(result).isEmpty();
assertThat(indexes).containsOnly(0);
}
@Test
public void inheritedStrategyMultipleNoninheritedComposedAnnotationsOnClass() {
MergedAnnotations annotations = MergedAnnotations.from(
MultipleNoninheritedComposedCachesClass.class,
SearchStrategy.INHERITED_ANNOTATIONS);
assertThat(stream(annotations, "value")).containsExactly("noninheritedCache1",
"noninheritedCache2");
}
@Test
public void getDirectFromClassWithMetaCycleAnnotatedClassWithMissingTargetMetaAnnotation() {
MergedAnnotation<?> annotation = MergedAnnotations.from(
MetaCycleAnnotatedClass.class, SearchStrategy.EXHAUSTIVE).get(
Component.class);
assertThat(annotation.isPresent()).isFalse();
}
@Test
public void exhaustiveStrategyMultipleNoninheritedComposedAnnotationsOnSuperclass() {
MergedAnnotations annotations = MergedAnnotations.from(
SubMultipleNoninheritedComposedCachesClass.class,
SearchStrategy.EXHAUSTIVE);
assertThat(stream(annotations, "value")).containsExactly("noninheritedCache1",
"noninheritedCache2");
}
@Test
public void exhaustiveStrategyOnBridgedMethodScansAnnotations() throws Exception {
Method source = BridgedMethod.class.getDeclaredMethod("method", String.class);
assertThat(source.isBridge()).isFalse();
assertThat(scan(source, SearchStrategy.EXHAUSTIVE)).containsExactly(
"0:TestAnnotation1", "1:TestAnnotation2");
}
@Test
public void collectMultiValueMapFavorsInheritedAnnotationsOverMoreLocallyDeclaredComposedAnnotations() {
MultiValueMap<String, Object> map = MergedAnnotations.from(
SubSubClassWithInheritedAnnotation.class,
SearchStrategy.INHERITED_ANNOTATIONS).stream(Transactional.class).collect(
MergedAnnotationCollectors.toMultiValueMap());
assertThat(map).contains(entry("qualifier", Arrays.asList("transactionManager")));
}
@Test
public void collectMultiValueMapFavorsInheritedComposedAnnotationsOverMoreLocallyDeclaredComposedAnnotations() {
MultiValueMap<String, Object> map = MergedAnnotations.from(
SubSubClassWithInheritedComposedAnnotation.class,
SearchStrategy.INHERITED_ANNOTATIONS).stream(Transactional.class).collect(
MergedAnnotationCollectors.toMultiValueMap());
assertThat(map).contains(entry("qualifier", Arrays.asList("composed1")));
}
@Test
public void getDirectFromClassWithInheritedAnnotationInterface() {
MergedAnnotation<?> annotation = MergedAnnotations.from(
InheritedAnnotationInterface.class, SearchStrategy.EXHAUSTIVE).get(
Transactional.class);
assertThat(annotation.getAggregateIndex()).isEqualTo(0);
}