Spring not picking up value defined in properties file - java

I have a class with inject attributes like so:
#RestController
public class MyController {
private final String myValue;
#Autowired
public MyController(
#Value("${config.myValue}") String myValue) {
this.myValue = myValue;
}
#PostMapping("/dostuff")
public String dostuff(#RequestBody String message) {
// stuff
}
}
And then I have a config file defined inside src/main/resources/application.yml like so:
config:
myValue: "some value"
But my IntelliJ (and cmd) tell me the value is not found:
Could not resolve placeholder 'config.myValue' in value "${config.myValue}"
Why is my defined value not being recognized? (I tried renaming file to application-default.yml and application.properties but that didn't help either)

Could you please try renaming file as application.properties and define property like below and check if it works?
config.myValue = some value

Related

How to convert a Properties Object to Custom Object using Jackson?

In a Spring Boot application, Spring Boot is used to build a Properties object from a YAML file as follows:
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
yamlFactory.setResources(new DefaultResourceLoader().getResource("application.yml"));
Properties properties = yamlFactory.getObject();
The reason why Spring Boot's own parser is used is that it not only reads YAML-compliant settings, but also dot-notated properties like e.g:
artist.elvis.name: "Elvis"
artist.elvis.message: "Aloha from Hawaii"
Now that the Properties object is built, I want to map it into an object like the following for example:
#JsonIgnoreProperties(ignoreUnknown = true)
private record Artist(Elvis elvis) {
private record Elvis(String name, String message) { }
}
My question is:
How can this be done with Jackson? Or is there another/better solution for this?
Many thanks for any help
I saw functionality like that in Ratpack framework.
e.g.:
var propsFileUrl =
Thread.currentThread()
.getContextClassLoader()
.getResource("application.properties");
ApplicationProperties applicationProperties =
ConfigData.builder()
.props(propsFileUrl)
.build()
.get(ApplicationProperties.class);
under the hood it is indeed done by using jackson's object mapper, but the logic is not as trivial to post it here.
here's the library:
https://mvnrepository.com/artifact/io.ratpack/ratpack-core/2.0.0-rc-1
application.yml is the default yml file, so no custom configuration is required. Value annotation should be able to read the properties.
#Value("${artist.elvis.name}")
private String name;
Next part I am not sure about your requirements, but hope this is what you are looking for.
To bind to this object 'constructor' can be a good option.
Class for elvis
#Bean
public class Elvis {
private String name;
private String message;
public Elvis(#Value("${artist.elvis.name"}) final String name, #Value("${artist.elvis.message"}) final String message) {
this.name=name;
this.message=message
}
// getter setter for name and message
}
Now Autowire the created bean to Artist bean
#Bean("artists")
public class Artists {
#Autowired
private Elvis elvis
pubic Elvis getElvis() {
return elvis;
}
}

Spring boot instantiate variable from #Value annotation

I have codes as below. I have variable values from application.properties file and how to assign it to another variable? In this case to coreApi variable.
Here is certainly fails because serverKey and clientKey is still null
And I don't want to initiate coreApi inside class action, I want it on variable init level.
Is this possible?
#Value(value = "${app.serverKey}")
String serverKey;
#Value(value = "${app.clientKey}")
String clientKey;
private CoreApi coreApi = new ConfigFactory(new Config(serverKey,clientKey)).getCoreApi();
Try something like this :
#Autowired
public void ConfigFactory(#Value("${app.serverKey}") String serverKey,#Value("${app.clientKey}") String clientKey) {
coreApi = new ConfigFactory(new Config(serverKey,clientKey)).getCoreApi();
}

Escape " (doublequote) in #Value property name

I have the following structure for a property:
my {
property {
item {
"1" {
value="some value"
}
"2" {
value="another value"
}
}
}
}
How do you refer to a property called "1" using the #Value annotation?
The example I have doesn't work. I tried the following options:
#Bean(name = "myProperty")
public String myProperty(#Value("${my.property.item.\"1\".value}") String myProperty) {
return myProperty;
}
#Bean(name = "myProperty")
public String myProperty(#Value("${my.property.item.'1'.value}") String myProperty) {
return myProperty;
}
#Bean(name = "myProperty")
public String myProperty(#Value("${my.property.item.1.value}") String myProperty) {
return myProperty;
}
None of which work.
Any advice appreciated!
Best way to fix that, is to just rename the properties, since java doesn't like when there are quotes inside of names.
Okay so Java definitely doesn't like the quotes in the name so my solution has instead (in my case) been to refer to the property using an alias although I realise this isn't apparent in the small example I gave (I didn't want to overcomplicate it).
In my example there's a set of property files that are imported into a Spring application.conf file.
Inside this application.conf file I put the following property:
myProperty.value=true
This overrides the other property
Then inside my original property file I simply refer to it.
my {
property {
item {
"1" {
value=${myProperty.value}
}
}
}
}
That means when I bind the property in a *Config.java file I can do:
#Bean(name = "myProperty")
public String myProperty(#Value("${myProperty.value}") String myProperty)
{
return myProperty;
}
Hope this helps people.

Spring - Set property value using annotations without using properties file

I have a bean class like, for example
class Sample {
private String message;
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
and I want to set this property's value.
In Xml Configuration, I could do
<bean id = "sample" class = "Sample"
<property name = "message" value = "Hello there!"/>
</bean>
How do I achieve the same thing i.e. set property's value using Java Annotation? Now I have read that we can use #Value annotation using some properties file but cannot it be done without using properties file, doing the way I did it through xml file? Or using properties file is necessary?
I was able to do it by including #Value("Hello there!") above the setter method. But I could feel that is not a good idea. How to set the property values for different instances using Java Annotations?
Thanks.
The value inserted into the #Value can come from places other than a properties file, for example it can also use system properties.
Using the guide here as a starting point should help you understand a little better.
As a basic and mostly useless usage example we can only inject “string
value” from the annotation to the field:
#Value("string value")
private String stringValue;
Using the #PropertySource annotation allows us to work with values
from properties files with the #Value annotation. In the following
example we get “Value got from the file” assigned to the field:
#Value("${value.from.file}")
private String valueFromFile;
We can also set the value from system properties with the same syntax.
Let’s assume that we have defined a system property named systemValue
and look at the following sample:
#Value("${systemValue}")
private String systemValue;
Default values can be provided for properties that might not be
defined. In this example the value “some default” will be injected:
#Value("${unknown.param:some default}")
private String someDefault;
You have a few options, depending on your requirements. In both of these examples you can set the annotation on a setter instead of the field.
Custom PropertySource
This lets you continue using #Value with greater control for how the properties are supplied. There are a large number of PropertySource implementations, but you can always create your own.
References:
How to add custom property source to Spring's Environment
PropertySource JavaDoc
Example:
#Configuration
class MyConfiguration {
#Bean
PropertySource myPropertySource(ConfigurableEnvironment env) {
MapPropertySource source = new MapPropertySource("myPropertySource", singletonMap("myPropertyValue", "example"));
env.getPropertySources().addFirst(source);
return source;
}
}
class Sample {
#Value("${myPropertyValue}")
private String message;
public String getMessage() {
return message;
}
}
String Bean
Define a bean as a String and auto-wire it using its qualifier.
Example:
#Configuration
class MyConfiguration {
#Bean
String myPropertyValue() {
String value;
// do something to get the value
return value;
}
}
class Sample {
#Autowired
#Qualifier("myPropertyValue")
private String message;
public String getMessage() {
return message;
}
}

Spring-boot: set default value to configurable properties

I have a properties class below in my spring-boot project.
#Component
#ConfigurationProperties(prefix = "myprefix")
public class MyProperties {
private String property1;
private String property2;
// getter/setter
}
Now, I want to set default value to some other property in my application.properties file for property1. Similar to what below example does using #Value
#Value("${myprefix.property1:${somepropety}}")
private String property1;
I know we can assign static value just like in example below where "default value" is assigned as default value for property,
#Component
#ConfigurationProperties(prefix = "myprefix")
public class MyProperties {
private String property1 = "default value"; // if it's static value
private String property2;
// getter/setter
}
How to do this using #ConfigurationProperties class (rather typesafe configuration properties) in spring boot where my default value is another property ?
Check if property1 was set using a #PostContruct in your MyProperties class. If it wasn't you can assign it to another property.
#PostConstruct
public void init() {
if(property1==null) {
property1 = //whatever you want
}
}
In spring-boot 1.5.10 (and possibly earlier) setting a default value works as-per your suggested way. Example:
#Component
#ConfigurationProperties(prefix = "myprefix")
public class MyProperties {
#Value("${spring.application.name}")
protected String appName;
}
The #Value default is only used if not overridden in your own property file.

Categories

Resources