@@ -100,14 +100,40 @@ public void findMethodAnnotationOnBridgeMethod() throws Exception {
100100 // }
101101
102102 @ Test
103- public void findAnnotationPrefersInterfacesOverLocalMetaAnnotations () {
103+ public void findAnnotationFavorsInterfacesOverLocalMetaAnnotations () {
104104 Component component = AnnotationUtils .findAnnotation (
105- ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface .class , Component .class );
105+ ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface .class , Component .class );
106+ assertNotNull (component );
106107
107108 // By inspecting ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface, one
108109 // might expect that "meta2" should be found; however, with the current
109110 // implementation "meta1" will be found.
111+ assertEquals ("meta1" , component .value ());
112+ }
113+
114+ @ Test
115+ public void findAnnotationFavorsInheritedAnnotationsOverMoreLocallyDeclaredComposedAnnotations () {
116+ Transactional transactional = AnnotationUtils .findAnnotation (SubSubClassWithInheritedAnnotation .class ,
117+ Transactional .class );
118+ assertNotNull (transactional );
119+
120+ // By inspecting SubSubClassWithInheritedAnnotation, one might expect that the
121+ // readOnly flag should be true, since the immediate superclass is annotated with
122+ // @Composed2; however, with the current implementation the readOnly flag will be
123+ // false since @Transactional is declared as @Inherited.
124+ assertFalse ("readOnly flag for SubSubClassWithInheritedAnnotation" , transactional .readOnly ());
125+ }
126+
127+ @ Test
128+ public void findAnnotationFavorsInheritedComposedAnnotationsOverMoreLocallyDeclaredComposedAnnotations () {
129+ Component component = AnnotationUtils .findAnnotation (SubSubClassWithInheritedMetaAnnotation .class ,
130+ Component .class );
110131 assertNotNull (component );
132+
133+ // By inspecting SubSubClassWithInheritedMetaAnnotation, one might expect that
134+ // "meta2" should be found, since the immediate superclass is annotated with
135+ // @Meta2; however, with the current implementation "meta1" will be found since
136+ // @Meta1 is declared as @Inherited.
111137 assertEquals ("meta1" , component .value ());
112138 }
113139
@@ -350,14 +376,15 @@ public void getRepeatableFromMethod() throws Exception {
350376 }
351377
352378
353- @ Component (value = "meta1" )
379+ @ Component (value = "meta1" )
354380 @ Order
355381 @ Retention (RetentionPolicy .RUNTIME )
382+ @ Inherited
356383 @interface Meta1 {
357384 }
358385
359- @ Component (value = "meta2" )
360- @ Transactional
386+ @ Component (value = "meta2" )
387+ @ Transactional ( readOnly = true )
361388 @ Retention (RetentionPolicy .RUNTIME )
362389 @interface Meta2 {
363390 }
@@ -395,6 +422,28 @@ static interface InterfaceWithMetaAnnotation {
395422 static class ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface implements InterfaceWithMetaAnnotation {
396423 }
397424
425+ @ Meta1
426+ static class ClassWithInheritedMetaAnnotation {
427+ }
428+
429+ @ Meta2
430+ static class SubClassWithInheritedMetaAnnotation extends ClassWithInheritedMetaAnnotation {
431+ }
432+
433+ static class SubSubClassWithInheritedMetaAnnotation extends SubClassWithInheritedMetaAnnotation {
434+ }
435+
436+ @ Transactional
437+ static class ClassWithInheritedAnnotation {
438+ }
439+
440+ @ Meta2
441+ static class SubClassWithInheritedAnnotation extends ClassWithInheritedAnnotation {
442+ }
443+
444+ static class SubSubClassWithInheritedAnnotation extends SubClassWithInheritedAnnotation {
445+ }
446+
398447 @ MetaMeta
399448 static class MetaMetaAnnotatedClass {
400449 }
@@ -453,6 +502,8 @@ public void overrideWithoutNewAnnotation() {
453502 @ Retention (RetentionPolicy .RUNTIME )
454503 @ Inherited
455504 @interface Transactional {
505+
506+ boolean readOnly () default false ;
456507 }
457508
458509 public static abstract class Foo <T > {
0 commit comments