Конфигурация Lambdaj FinalClassArgumentCreators для всего приложения. Где и как это сделать?

У нас возникла проблема с настройкой lambdaj для работы с Joda Time. Так как LocalDate является окончательным классом, Lambdaj необходимо инициализировать следующим образом: (см. ошибку 70)

public class LocalDateArgumentCreator implements FinalClassArgumentCreator<LocalDate> {
    private final long MSECS_IN_DAY = 1000L * 60L * 60L * 24L;
    public LocalDate createArgumentPlaceHolder(int seed) {
        return new LocalDate((long)seed * MSECS_IN_DAY);
    }
}
ArgumentsFactory.registerFinalClassArgumentCreator(LocalDate.class, new LocalDateArgumentCreator());

Поскольку нам нужно, чтобы эта конфигурация применялась практически везде, у нас не хватает вариантов, как это реализовать. Наше приложение представляет собой веб-приложение, основанное на Spring и Wicket.

Я придумал три разных варианта:

1. Статический блок инициализации в основном модуле maven

Поскольку основной модуль включен в любой другой модуль, все модули будут включать класс. Остается вопрос: инициализируются ли статические блоки всегда, даже если нет ссылок на целевой класс?

Пример

public final class LambdajInitializer {
    static {
        // initialize like above
    }
}

2. Инициализирующий компонент в applicationContext.xml

Недостаток: никогда не инициализируется для тестов, отличных от Spring.

Пример: в applicationContext-core.xml (входит в каждый модуль)

<bean class="...LambdajInitializer" />

public class LambdajInitializer {
    @PostConstruct
    public void init() {
        // Lambdaj initialization
    }
}

3. Вызов метода инициализации в классе приложения Wicket

Недостаток: никогда не инициализируется вне веб-модуля.

public class MyApplication extends WebApplication {
    @Override
    public void init() {
        ...
        // Lambdaj initialization
        ...
    }
}

Мой вопрос: какой предпочтительный способ добиться этого?


person RJo    schedule 11.12.2012    source источник
comment
Вы упускаете вопрос...   -  person Atropo    schedule 11.12.2012
comment
Да, случайно выложил слишком рано.   -  person RJo    schedule 11.12.2012


Ответы (2)


  1. Я бы избегал инициализации static, так как в будущем у вас могут быть (насколько маловероятно ваше обращение) модули, которым не потребуется такая инициализация. Мне не нравятся static инициализации.
  2. Это разумный подход, вы можете поместить эту инициализацию в раздел @Before ваших модульных тестов без весны.
  3. Как и для 2., вы можете инициализировать код в своих @Before разделах.

Вариант 4. вы можете создать тестовый класс/файл конфигурации Spring и передать его своим тестам, используя @ContextConfiguration

person Alessandro Santini    schedule 18.12.2012
comment
Я не так беспокоюсь о тестах, как о производственном коде. Если инициализация не была выполнена в тестах, они просто потерпят неудачу, что в данном случае при использовании операций Lambdaj на LocalDates. Проблема в том, что проблема может быть не обнаружена модульными тестами, поскольку она каким-то образом зависит от порядка выполнения (в кластере производственной среды другой сервер вышел из строя, а другой нет). - person RJo; 18.12.2012

Мы пришли к следующему выводу:

  1. Во время выполнения приложения мы инициализируем FinalClassArgumentCreators Lambdaj в методе init() класса приложения Wicket. Таким образом, они почти наверняка будут инициализированы до любого использования Lambdaj.
  2. Для тестирования компонентов и страниц Wicket мы создали собственный класс TestApplication, в котором используется тот же код инициализации, что и в рабочем приложении.
  3. Для отдельных пакетных заданий мы решили не использовать Lambdaj. Если позже мы решим использовать его, мы, вероятно, извлечем инициализацию в класс, экземпляр которого создаст Spring.
person RJo    schedule 27.12.2012