0

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()

3
  • Assuming MantilUpdateReadVO is indeed a Spring bean (if not, Spring will never inject anything in it), then add SoapUri as a constructor argument, and remove the useless field. Commented Mar 29, 2019 at 17:48
  • @JBNizet I tried passing new SoapUri().getMantilUpdate() as constructor argument but it is null. Commented Mar 29, 2019 at 17:52
  • 2
    MantilUpdateReadVO,MantilUpdate,RequestClientVO are spring beans? Commented Mar 29, 2019 at 18:22

1 Answer 1

1

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!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.