Динамическое добавление конфигурации контекста spring во время выполнения?

#java #spring #junit

#java #spring #junit

Вопрос:

В spring / junit вы можете загружать файлы контекста приложения с помощью @ContextConfiguration таких

 @ContextConfiguration({"classpath:a.xml", "classpath:b.xml"})
  

У меня есть требование, согласно которому, если я вижу специальную аннотацию к тестовому классу, то динамически добавляю другой файл контекста XML. Например:

 @ContextConfiguration({"classpath:a.xml", "classpath:b.xml"})
@MySpecialAnnotation 
class MyTest{
...
}
  

В приведенном выше примере я бы также искал @MySpecialAnnotation и добавлял special-context.xml . Каков наилучший способ сделать это? Я некоторое время смотрел на это, и кажется, что мой собственный подкласс, ContextLoader который является одним из параметров для @ContextConfiguration , является лучшим подходом? Правильно ли это? Есть ли лучший способ сделать это?

Комментарии:

1. Что вы подразумеваете под динамическим. Аннотация статична, она не меняется во время выполнения?

2. Очевидно, что это и есть та проблема, которую я пытаюсь решить. Я бы хотел динамически добавлять новый контекст в список файлов, которые загружает spring.

3. Но в чем смысл этой аннотации? Что должно вызвать команду «теперь добавить контекст x»?

4. @Ralph все выполняется в среде spring и junit. Я спрашиваю, есть ли дескриптор или обратный вызов, где я могу это контролировать. Что должно вызвать обратный вызов — вот мой вопрос.

5. можете ли вы предоставить фактическое требование, описывающее причину, стоящую за этим? Я считаю, что то, что вы пытаетесь сделать, может быть решено без изменения возможностей ApplicationContext «на лету».

Ответ №1:

Оказывается, лучшее решение — создать мой собственный ContextLoader. Я сделал это, расширив абстрактную конфигурацию.

 public class MyCustomContextListener extends GenericXmlContextLoader implements ContextLoader {
    @Override
    protected String[] generateDefaultLocations(Class<?> clazz) {
        List<String> locations = newArrayList(super.generateDefaultLocations(clazz));
        locations.addAll(ImmutableList.copyOf(findAdditionalContexts(clazz)));
        return locations.toArray(new String[locations.size()]);
    }

    @Override
    protected String[] modifyLocations(Class<?> clazz, String... locations) {
        List<String> files = newArrayList(super.modifyLocations(clazz, locations));
        files.addAll(ImmutableList.copyOf(findAdditionalContexts(clazz)));
        return files.toArray(new String[files.size()]);
    }

    private String[] findAdditionalContexts(Class<?> aClass) {
        // Look for annotations and return 'em
    }
}
  

Комментарии:

1. Как добавить и создать тестовый пример для того же самого (не набор, но нужен тестовый пример) для перекрестной проверки и валидации?

Ответ №2:

Возможно, вы можете использовать профили Spring 3.1 для достижения этой цели.

Если вы поместите компоненты, определенные в special-context.xml в профиль с именем special вы можете активировать специальный профиль, используя @Profile(«специальный») в вашем классе.

Это полностью устранило бы необходимость в вашей специальной аннотации.