Перейти к основному содержимому

How to Inject a Property Value Into a Class Not Managed by Spring?

· 3 мин. чтения

1. Overview

By design, classes annotated with @Repository, @Service, @Controller , etc. are managed by Spring and injecting configuration there is easy and natural. What's not as simple is passing configuration to classes that are not directly managed by Spring.

In that case, we can use ClassLoader- based configuration loading or simply instantiate our classes in another bean and set required params manually – this is the suggested option because configuration entries don't need to be stored in *.properties files exclusively.

In this quick article, we are going to cover the topic of loading *.properties files with Java ClassLoader as well as injection of already loaded configuration by Spring into an unmanaged class.

2. Load Configuration With Class Loader

Simply put, *.properties files are resources files holding some config info. Instead of using third party implementations that support automatic application configuration loading, e.g. that implemented in Spring, we can use Java ClassLoader to do the same.

We're going to create a container object that will hold Properties defined in resourceFileName . To fill up the container with configuration, we will use a ClassLoader .

Let's define PropertiesLoader class that implements loadProperties(String resourceFileName) method:

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 загрузки (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 .