«1. Обзор

По дизайну классы, аннотированные @Repository, @Service, @Controller и т. д., управляются Spring, и внедрение конфигурации происходит легко и естественно. Что не так просто, так это передача конфигурации классам, которые не управляются непосредственно Spring.

В этом случае мы можем использовать загрузку конфигурации на основе ClassLoader или просто создать экземпляры наших классов в другом bean-компоненте и установить необходимые параметры вручную — это рекомендуемый вариант, поскольку записи конфигурации не нужно хранить в *.properties исключительно файлы.

В этой быстрой статье мы рассмотрим тему загрузки файлов *.properties с помощью Java ClassLoader, а также внедрения Spring уже загруженной конфигурации в неуправляемый класс.

2. Загрузка конфигурации с помощью загрузчика классов

Проще говоря, файлы *.properties — это файлы ресурсов, содержащие некоторую информацию о конфигурации. Вместо использования сторонних реализаций, поддерживающих автоматическую загрузку конфигурации приложения, например. который реализован в Spring, мы можем использовать Java ClassLoader, чтобы сделать то же самое.

Мы собираемся создать объект-контейнер, который будет содержать свойства, определенные в resourceFileName. Чтобы заполнить контейнер конфигурацией, мы будем использовать ClassLoader.

Давайте определим класс PropertiesLoader, реализующий метод loadProperties(String resourceFileName):

public class PropertiesLoader {

    public static Properties loadProperties(String resourceFileName) throws IOException {
        Properties configuration = new Properties();
        InputStream inputStream = PropertiesLoader.class
          .getClassLoader()
          .getResourceAsStream(resourceFileName);
        configuration.load(inputStream);
        inputStream.close();
        return configuration;
    }
}

Каждый объект Class содержит ссылку на ClassLoader, создавший его экземпляр; это объект, который в первую очередь отвечает за загрузку классов, но в этом руководстве мы будем использовать его для загрузки файла ресурсов вместо простого класса Java. ClassLoader ищет resourceFileName в пути к классам.

После этого мы загружаем файл ресурсов как InputStream через API getResourceAsStream.

В приведенном выше примере мы определили контейнер конфигурации, который может анализировать имя_файла_ресурса, используя API load(InputStream).

Метод load реализует разбор файлов *.properties с поддержкой символов «:» или «=» в качестве разделителей. Кроме того, оба символа «#» или «!», используемые в начале новой строки, являются маркерами комментария и вызывают игнорирование этой строки.

Наконец, давайте прочитаем точное значение определенной записи конфигурации из наших файлов конфигурации:

String property = configuration.getProperty(key);

3. Загрузка конфигурации с помощью Spring

Второе решение — использовать функцию Spring Spring для обработки некоторых из низкоуровневая загрузка и обработка файлов.

Давайте определим Initializer, который будет содержать конфигурацию, необходимую для инициализации нашего пользовательского класса. Во время инициализации Bean фреймворк загрузит все поля, аннотированные @Value, из файла конфигурации *.properties:

@Component
public class Initializer {

    private String someInitialValue;
    private String anotherManagedValue;

    public Initializer(
      @Value("someInitialValue") String someInitialValue,
      @Value("anotherValue") String anotherManagedValue) {
 
        this.someInitialValue = someInitialValue;
        this.anotherManagedValue = anotherManagedValue;
    }

    public ClassNotManagedBySpring initClass() {
        return new ClassNotManagedBySpring(
          this.someInitialValue, this.anotherManagedValue);
    }
}

Инициализатор теперь может отвечать за создание экземпляра ClassNotManagedBySpring.

Теперь мы просто получим доступ к нашему экземпляру Initializer и запустим на нем метод initClass(), чтобы обработать создание экземпляра нашего пользовательского класса ClassNotManagedBySpring:

ClassNotManagedBySpring classNotManagedBySpring = initializer.initClass();

Получив ссылку на Initializer, мы сможем создайте экземпляр нашего пользовательского ClassNotManagedBySpring.

4. Резюме

В этом кратком руководстве мы сосредоточились на чтении свойств в Java-классе, отличном от Spring.

Как всегда, пример реализации можно найти на GitHub.