Самый быстрый и наименее обремененный способ сделать это - написать свой собственный. Это не должно быть так сложно - возможно, потребуется несколько часов, чтобы написать тесты и собрать код.
Предлагаемый алгоритм:
Начните с загрузки файла свойств в объект Properties.
Возьмите средство чтения ввода (используйте BufferedReader, если вы будете читать файлы из источника с высокой задержкой) и захватите каждый символ в поисках {. Если символ не является {, выведите символ в выходной поток. Если вы нашли {, начните поиск для}, накапливая символы в StringBuilder. Если вы нажмете другой {, сбросьте StringBuilder в выходной поток и начните сначала. Возможно, вы захотите иметь максимальное количество символов, которое вы разрешаете указывать ключу свойства. Если вы достигнете этого предела, сбросьте StringBuilder в выходной поток.
Если вы найдете токен в окружении {}, возьмите имя ключа и выполните вызов Properties # getProperty (). Если вы получите результат, отправьте результат в выходной поток. Если вы не получите результат, сделайте что-то другое.
Если вы хотите стать умнее, как только вы получите результат, вместо того, чтобы отправлять результат непосредственно в выходной поток, предварительно ожидайте его во входном потоке (не буквально - вам нужно было бы сделать некоторую логику, чтобы заставить его работать) и продолжить. Таким образом, если какое-либо из свойств само ссылается на другие свойства, алгоритм фактически становится рекурсивным.
Если вы действительно стремитесь к производительности, вы можете использовать ByteBuffer вместо входного потока / устройства записи