SoT
SoT

Reputation: 1203

Spring @Value doesn't work in nested configuration

I have a application.properties:

app.cert.identity.subject.organizationalUnit=test
app.cert.identity.subject.O=Pacific College
app.cert.identity.subject.L=CanTho
app.cert.identity.subject.ST=CanTho
app.cert.identity.subject.C=VN

My class:

@Configuration
@ConfigurationProperties(prefix = "app.cert.identity")
@EnableConfigurationProperties
@Data
public class IdentityCertificateDefinition {

    private Subject subject;

    @Data
    @Configuration
    public static class Subject {

        private String organizationalUnit;    //Does work

        @Value("${app.cert.identity.subject.O}")    //Does NOT work
        private String organization;

        @Value("${app.cert.identity.subject.L}")    //Does NOT work
        private String location;

        @Value("${app.cert.identity.subject.ST}")    //Does NOT work
        private String state;

        @Value("${app.cert.identity.subject.C}")    //Does NOT work
        private String countryCode;

        @Value("${app.cert.identity.validity.not-after-in-days}")    //Does NOT work
        private int notAfterInDays;

    }

}

And here is the result: enter image description here You guys can see just the organizationalUnit work, the rest doesn't work (all are null). I do not know how to make the rest properties work. I would like to keep application.properties.

Upvotes: 3

Views: 2011

Answers (2)

Milgo
Milgo

Reputation: 2767

You can use the static class configuration with this code:

@Configuration
@Data
public class IdentityCertificateDefinition {

    @Autowired
    private Subject subject;

    @Data
    @Configuration
    public static class Subject {

        private String organizationalUnit;

        @Value("${app.cert.identity.subject.O}")
        private String organization;

        @Value("${app.cert.identity.subject.L}")
        private String location;

        @Value("${app.cert.identity.subject.ST}")
        private String state;

        @Value("${app.cert.identity.subject.C}")
        private String countryCode;

        @Value("${app.cert.identity.validity.not-after-in-days}")
        private int notAfterInDays;
    }
}

If you don't need to use a static class in a configuration class, just use:

@Configuration
@Data
public class IdentityCertificateDefinition {

    @Value("${app.cert.identity.subject.OU}")
    private String organizationalUnit;

    @Value("${app.cert.identity.subject.O}")
    private String organization;

    @Value("${app.cert.identity.subject.L}")
    private String location;

    @Value("${app.cert.identity.subject.ST}")
    private String state;

    @Value("${app.cert.identity.subject.C}")
    private String countryCode;

    @Value("${app.cert.identity.validity.not-after-in-days}")
    private int notAfterInDays;
}

Upvotes: 2

sigur
sigur

Reputation: 692

The problem should be related to

@ConfigurationProperties(prefix = "app.cert.identity")

Mainly you're say the properties have a common prefix, but then when you inject their values your putting the prefix again:

 @Value("${app.cert.identity.subject.L}")

So Spring is acting to find a property named (prefix + class + value of @Value):

 @Value("${app.cert.identity.subject.app.cert.identity.subject.L}")

Change

@Value("${app.cert.identity.subject.L}")

To

@Value("${L}")

Upvotes: 2

Related Questions