chens
chens

Reputation: 61

Set @Value to use @ConfigurationProperties prefix

I'm using a properties file with the value: com.abc.cpuUtilization.okThreshold = 0.5

I want to use the following configuration class:

@Component
@ConfigurationProperties(prefix="com.abc")
public class SystemConfiguration{

  @Value("${cpuUtilization.okThreshold}")
  private Double cpuUtilizationOkThreshold;

  // getters and setters of cpuUtilizationOkThreshold
  }
}

But I get an exception of Could not resolve placeholder 'cpuUtilization.okThreshold'

When setting @Value to be: "${com.abc.cpuUtilization.okThreshold}" it works, but it makes the code look ugly and cumbersome.

Is there a way to configure this class, so I will not have to write the whole prefix for the @Value annotation?

Upvotes: 6

Views: 17321

Answers (6)

Dasari Swaroop Kumar
Dasari Swaroop Kumar

Reputation: 169

As thepaoloboi said, The @ConfigurationProperties(prefix="com.abc") annotation will allow you to bind fields via their name. If you specify a prefix of "com.abc" and you have a variable named "cpuUtilization", the value of the variable will be that of the "com.abc.cpuUtilization" property.

The @Value annotation fetches the property with the exact same name. @Value("${cpuUtilization.threshold}") will fetch the property with that exact name. It does not take the prefix into account.

Upvotes: 1

danyPasillas
danyPasillas

Reputation: 166

First of all, change your "cpuUtilization.okThreshold" value to com.abc.cpuUtilization-okThreshold = 0.5

Then in the config class:

@Component
@ConfigurationProperties("com.abc")
public class SystemConfiguration{

  private Double cpuUtilizationOkThreshold;

  // getters and setters of cpuUtilizationOkThreshold
  }
}

Try to configure without using "prefix" and without using the @Value annotation, it worked for me.

Upvotes: 0

thepaoloboi
thepaoloboi

Reputation: 878

Spring configuration properties scanning works like package scanning.

The @Value annotation works with the full property name, or a raw string value. And so the value you set should be. Assume to have the com.abc.cpu-utilization.okThreshold=0.5 property.

  • Solution 1: your SystemConfiguration modify the prefix and delete the @Value:

    @Getter
    @Setter
    @Configuration
    @ConfigurationProperties(prefix = "com.abc.cpu-utilization")
    public class SystemConfiguration {
       private Double okThreshold;
    }
    
  • Solution 2: your SystemConfiguration could point to com.abc and contain an inner configuration for the cpu-utilization intermediate package:

    @Getter
    @Setter
    @Configuration
    @ConfigurationProperties(prefix = "com.abc")
    public class SystemConfiguration {
       private CpuUtilizationConfig cpuUtilization;
    }
    
    @Data
    public class CpuUtilizationConfig {
        private Double okThreshold;
    }
    

Note that okThreshold and cpuUtilization directly reflect the property naming we have prior defined. Then, Spring will do the magic :-)

See:

Upvotes: 3

Ajit Kumar Singh
Ajit Kumar Singh

Reputation: 378

@ConfigurationProperties works best with hierarchical properties that all have the same prefix therefore, you add a prefix of com.abc.cpuUtilization.Your POJO class Should be like

@Configuration
@ConfigurationProperties(prefix="com.abc.cpuUtilization")
public class SystemConfiguration{

  private Double okThreshold;

  public Double getOkThreshold() {
        return okThreshold;
    }

    public void setOkThreshold(Double okThreshold) {
        this.okThreshold = okThreshold;
    }

  }
}

If you don't use @Configuration in the POJO, then you need to add @EnableConfigurationProperties(ConfigProperties.class) in the main Spring application class to bind the properties into the POJO. Then you can set value in application.properties

com.abc.cpuUtilization.okThreshold=0.5

Refer:https://www.baeldung.com/configuration-properties-in-spring-boot

Upvotes: 0

Chris Neve
Chris Neve

Reputation: 2424

The @ConfigurationProperties(prefix="com.abc") annotation will allow you to bind fields via their name. As @Olgun YILDIZ stated, if you specify a prefix of "com.abc" and you have a variable named "cpuUtilization" , the value of the variable will be that of the "com.abc.cpuUtilization" property. (In fact, you could even name your variable "cpuutilization" , "cpu_utilization" , "cpu-utilization" or "CPU_UTILIZATION" because of Spring's relaxed rules for binding properties).

The @Value annotation fetches the property with the exact same name. @Value("${cpuUtilization.threshold}") will fetch the property with that exact name. It does not take the prefix into account.

Either you do as @Olgun suggested (prefix of "com.abc.cpuUtilization" and variable name "okThreshold" ) or you set the whole property name in the @Value.

Upvotes: 0

olgunyldz
olgunyldz

Reputation: 564

For congiuation propertiestion you just need to add the values in proeprties file with the same key with the variable.

in application.properties.

com.abc.cpuUtilization.okThreshold=123

Your class should be:

@Component
@ConfigurationProperties(prefix="com.abc.cpuUtilization")
public class SystemConfiguration{

  private Double okThreshold;

  }
}

Upvotes: 0

Related Questions