Spring autowire статического объекта конфигурации не работает

как новичок в Spring, я пытаюсь загрузить внешнюю конфигурацию в Configuration-Object, который затем пытаюсь автоматически подключить.

Ниже приведены мои настройки, разбитые до минимума (меньше полей): Структура пакета:

app
  |--Application.java
app.configuration
  |--ConfigProperties.java

С моим configuration.properties проживающим:

src/main/resources/config

Application.java:

package app;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import app.configuration.ConfigProperties;

@SpringBootApplication
public class Application
{
    //just to test if autowire works
    @Autowired
    public static ConfigProperties config;

    public static void main(String[] args)
    {
        SpringApplication.run(Application.class, args);

        System.out.println(config.getId());
    }
}

ConfigProperties.java:

package app.configuration;

import javax.validation.constraints.NotBlank;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.validation.annotation.Validated;

@Configuration
@PropertySource("classpath:/config/configuration.properties")
@ConfigurationProperties
@Validated
public class ConfigProperties
{

    @NotBlank
    private String id;

    public String getId()
    {
        return id;
    }

    public void setId(String id)
    {
        this.id = id;
    }

}

Это приводит к исключению NullPointerException для строки:

System.out.println(config.getId());

в Apllication.java.

Я прочитал несколько сообщений по этой теме, но большинство из них подразумевает, что собственное создание экземпляров предотвращает автоматическое подключение, чего я не делаю, или что сканирование не может найти класс для автоматического подключения, но из того, что я прочитал, с моими аннотациями и структурой пакета, которые не должны быть проблема.

Где мои ошибки?

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
252
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий
@Autowired
public static ConfigProperties config;

Вы не можете автоматически подключать поля static в Spring.

//just to test if autowire works

Вы можете написать для этого новые тестовые примеры Junit.

Что-то вроде:

@Autowired
public ConfigProperties config;

в вашем тестовом классе.

Я этого не знал; спасибо за быстрый ответ. assertNotNull-test кажется пройденным.

Wolfone 30.04.2018 16:48

Не используйте статический ConfigProperties. Затем используйте @PostConstruct, чтобы распечатать идентификатор из вашего объекта конфигурации.

@Autowired
ConfigProperties config;

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

@PostConstruct 
void printId(){
    System.out.println("ID = " + config.getId());
}

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

public static ConfigProperties config;

@Autowired
public Application(ConfigProperties config) {
    Application.config= config;
}

Как вариант, взгляните на аннотацию @PostConstruct.

Другие вопросы по теме