I am trying to create a configuration properties class that has a recursive class, structured similarly to a linked list. I'm using Spring boot 2.0.6.RELEASE, and the class is being autowired using @EnableConfigurationProperties({EnginealConfig.class})
.
The issue I am having is that only one the first level will be bound to the Test object, x.test
will never get set.
Using the following application.properties file:
engineal.x.value: "Test1"
engineal.x.test.value: "Test2"
engineal.x.test.test.value: "Test3"
And the following configuration properties class:
@ConfigurationProperties(prefix = "engineal")
public class EnginealConfig {
static class Test {
private String value;
private Test test;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Test getTest() {
return test;
}
public void setTest(Test test) {
this.test = test;
}
@Override
public String toString() {
return "Test{" +
"value='" + value + '\'' +
", test=" + test +
'}';
}
}
private Test x;
public Test getX() {
return x;
}
public void setX(Test x) {
this.x = x;
}
@Override
public String toString() {
return "EnginealConfig{" +
"x=" + x +
'}';
}
}
the object will print EnginealConfig{x=Test{value='Test1', test=null}}
. Unfortunately the recursion is not working.
After messing around trying different things to get this to work, I tried changing EnginealConfig#Test.test from private Test test;
to private List<Test> test;
, along with the getters and setters. Then by using lists with one element, this recursion works.
The following application.properties with the List<Test>
change:
engineal.x.value: "Test1"
engineal.x.test[0].value: "Test2"
engineal.x.test[0].test[0].value: "Test3"
will output EnginealConfig{x=Test{value='Test1', test=[Test{value='Test2', test=[Test{value='Test3', test=null}]}]}}
. I can then access the next element by using test.get(0)
.
So it appears as if recursion is supported only if the recursive type is in a collection.
While this workaround is ok, I would prefer to use my first way of doing it. Are/should recursive classes be supported without needing a collection? Thank you for your help!
Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.
@ConfigurationProperties provides validation of properties using the JSR-303 format. This allows all sorts of neat things.
properties in default location. Spring Boot loads the application. properties file automatically from the project classpath. All you have to do is to create a new file under the src/main/resources directory.
Just set your inner class as an individual class, then everything would work well.
application.yml
simple:
value: aa
myTest:
value: lower
config class
@ConfigurationProperties(prefix = "simple")
@Data //It is for getter setter
public class SimpleConfig {
private String value;
private MyTest myTest;
}
the recursion class
@Data
public class MyTest {
private String value;
private MyTest myTest;
}
Test case
@Resource
private SimpleConfig simpleConfig;
@Test
public void myTest(){
String value = simpleConfig.getValue();
System.out.println("outerValue : " + value);
String innerValue = simpleConfig.getMyTest().getValue();
System.out.println("innerValue :" + innerValue);
}
result
outerValue : aa
innerValue :lower
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With