Встроенная аннотация для Java аннотации

Im пишу TestCases для моего RestControllers
Для каждого ControllerTest calss я использую следующие аннотации

@WebAppConfiguration
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebConfig.class, TestAppConfig.class})

Итак, я решил определить свою собственную аннотацию, содержащую все эти аннотации, подобные этой

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@WebAppConfiguration
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebConfig.class, TestAppConfig.class})
public @interface ControllerTest {
}

Затем я использовал только одну аннотацию для всех моих ControllerTest classes

@ControllerTest
public class XXControllerTest {
}

После этой модификации тесты завершились неудачно с помощью

java.lang.IllegalArgumentException: WebApplicationContext is required
    at org.springframework.util.Assert.notNull(Assert.java:115)

И чтобы он снова работал, мне потребовалось добавить @RunWith(SpringJUnit4ClassRunner.class) в Test class

@ControllerTest
@RunWith(SpringJUnit4ClassRunner.class)
public class XXControllerTest {
}

Мой вопрос в том, почему моя аннотация @ControllerTest не работает, пока она содержит аннотацию @RunWith(SpringJUnit4ClassRunner.class)? есть ли что-нибудь особенное в аннотации @RunWith? или я что-то пропустил?

PS: Я использую тот же подход для Spring config classes, и они работают нормально.

Ответ 1

Этот механизм, в котором вы можете иметь "мета-аннотации", которые сами аннотируются другими аннотациями, которые затем применяются к классу, на котором вы помещаете мета-аннотацию, является тем, что характерно для Spring Framework. Это не стандартная функция аннотаций Java.

Это не работает, потому что JUnit не понимает этот механизм. Аннотация @RunWith представляет собой аннотацию JUnit. JUnit не понимает, что он должен смотреть аннотации, которые находятся в мета-аннотации @ControllerTest.

Таким образом, этот механизм работает с аннотациями, которые обрабатываются с помощью Spring, но не с аннотациями, которые обрабатываются другими инструментами, такими как JUnit.

Ответ 2

Создание meta-annotations из spring аннотаций - это функция spring, а @RunWith - аннотация JUnit.