Как получить доступ к значениям application.properties в конструкторе

#java #spring-boot

#java #весенняя загрузка

Вопрос:

Я пытаюсь использовать @ConfigurationProperties для загрузки key-value пар из application.properties файла.

application.properties

 soap.action.segalRead=Segal/SegalRead
soap.action.mantilUpdate=Mantil/MantilUpdate
  

SoapUri.java

 @ConfigurationProperties(prefix = "soap.action")
public class SoapUri {

    @NotNull
    private String segalRead;
    @NotNull
    private String mantilUpdate;

    //getters and setters
}
  

SoapUriTests.java

 @RunWith(SpringRunner.class)
@SpringBootTest
public class SoapUriTests {

    @Autowired 
    private SoapUri soapUri;

    @Test
    public void testSoapUri_returnsSoapAction() {
        assertThat(soapUri.getSegalRead()).isEqualTo("Segal/SegalRead");
        assertThat(soapUri.getMantilUpdate()).isEqualTo("Mantil/MantilUpdate");
    }
}
  

Приведенный выше модульный тест отлично работает.

Однако мне нужно использовать SoapUri в реальном коде. Рассмотрим следующий код:

 public class MantilUpdateReadVO extends RequestClientVO {

    @Autowired
    private SoapUri soapUri;

    public MantilUpdateReadVO(final MantilUpdate mantilUpdate) {
        super(mantilUpdate, soapUri.getMantilUpdate(), MantilUpdateResponse.class);
    }
}
public class RequestClientVO {

    private Object readRequest;
    private String serviceName;
    private Class<?> unmarshalTargetclass;

    public MwsRequestClientVO(Object readRequest, String serviceName, Class<?> unmarshalTargetclass) {
        super();
        this.readRequest = readRequest;
        this.serviceName = serviceName;
        this.unmarshalTargetclass = unmarshalTargetclass;
    }
    //getters and setters
}
  

Выше жалуется на: «Не удается ссылаться на поле экземпляра soapUri при явном вызове конструктора«

Кто-нибудь знает обходной путь для внедрения segalRead и mantilUpdate в constructor из super()

Комментарии:

1. Предполагая, что mantillupdatereadvo действительно является Spring bean (если нет, Spring никогда ничего в него не добавит), затем добавьте SoapUri в качестве аргумента конструктора и удалите бесполезное поле.

2. @JBNizet Я пытался передать новый SoapUri().getmanitiplupdate() в качестве аргумента конструктора, но он равен нулю.

3. MantilUpdateReadVO MantilUpdate , RequestClientVO являются ли spring beans?

Ответ №1:

Вы используете внедрение поля, что не является хорошей идеей. Подробности см. в книге Оливера Гирке «Почему внедрение поля — зло«.

Поле не может быть введено до тех пор, пока не будет создан экземпляр; таким образом, вы не можете использовать введенное поле во время построения.

Измените код следующим образом:

     @Autowired
    public MantilUpdateReadVO(final SoapUri soapUri, final MantilUpdate mantilUpdate) {
        super(mantilUpdate, soapUri.getMantilUpdate(), MantilUpdateResponse.class);
    }
  

Вам также необходимо убедиться, что MantilUpdateReadVO это компонент Spring; возможно, потребуется добавить @Component .

Удачи!