Angelina
Angelina

Reputation: 2265

How to access application.properties values in constructor

I am trying to use @ConfigurationProperties to load key-value pairs from application.properties file.

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");
    }
}

Above unit test works great.

However, I need to use SoapUri in real code. Consider following code:

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
}

Above complains about: "Cannot refer to an instance field soapUri while explicitly invoking a constructor"

Does anyone know a workaround for injecting segalRead and mantilUpdate in constructor of super()

Upvotes: 0

Views: 1318

Answers (1)

Jamie Bisotti
Jamie Bisotti

Reputation: 2675

You are using field-injection, which is not a good idea. See Oliver Gierke's Why Field Injection is Evil for details.

The field cannot be injected until after the instance is constructed; so, you cannot use an injected field during construction.

Change the code like this:

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

You also need to ensure MantilUpdateReadVO is a Spring Bean; might need to add @Component.

Good luck!

Upvotes: 1

Related Questions