Платформо-зависимые настройки

Имеем Java web-приложение с использование Spring Framework. Стоит задача реализовать поддержку конфигурации приложения в зависимости от платформы, на которой приложение развернуто.

Естественно, что в случае с подключением различных баз данных лучшим вариантом будет использование, встроенной в Java, технологии JNDI. Но кроме подключения к базам данных случаются и другие оказии.

Решение достаточно тривиально — заставить Spring Framework загружать различные .properties файлы для различных окружений.
Конструкция #{ systemEnvironment[ 'SUPER_APP_ENV' ] } вычитывает указанную переменную окружения.

Собственно логика написанного достаточно проста. Предположим, что переменная окружения SUPER_APP_ENV имеет значение production. Сначала загружается application.properties, содержащий значения по-умолчанию, после этого вычитывается application-production.properties, данные из второго файлы затирают данные из первого, частично или полностью в зависимости от степени пересечения.

Cтоит оговорить некоторые детали реализации. Конструкция #{ systemEnvironment[ '...' ] } основана на Spring EL, а следовательно поддерживается только Spring 3, вместо нее можно использовать ${ ... }. Но для меня этот вариант не работал, поскольку используемый в моем проекте Hudson в комбинации с Maven упрямо затирали указанную конструкцию текущим значением переменной. Причем параметризованная сборка в Hudson была отключена, а Maven сам по себе затирает только конструкции вида ${ env.SUPER_APP_ENV }. В общем элемент мистики присутствует.

Следует подчеркнуть, что подобный подход будет хорошо работать только в случае, если имеется малое количество платформ развертывания и им можно полностью доверять. Типичный пример — существует только production, testing и development окружение. В случае большого количества неизвестных платформ развертывания такой подход по понятным причинам работать не будет.