Reputation: 46
I am new to Java and spring boot. I am trying to create simple application where some data will be read from config.yml file like url and file for different server to update the data from file. My config.yml looks like this.
appserver1:
url: http://localhost:8080/api1
file: \file1.txt
appserver2:
url: http://localhost:8081/api2
file: \file2.txt
appserver3:
url: http://localhost:8082/api3
file: \file3.txt
I created 3 class where naming AppServer1 , AppServer2 and AppServer3 all have only 2 property containing URL and file path.
public class AppServer1 {
private String URL;
private String filePath;
public String getURL() {
return URL;
}
public void setURL(String URL) {
this.URL = URL;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
}
How can I make the configuration such that I can use the above classes as Autowired where ever I need to access the AppServer1 or AppServer2 or AppServer3 all over my project. For eg. - If I want to use AppServer1 details I can directly Autowired AppServer1 and use the URL and File path in that class.
I have tried 1 solution using @Value but wanted to know if there is any other as if my config file is big so using @Value will be too hard. Below is the code I tried.
@Configuration
public class AppServer1 {
@Value("${appserver1.url}")
private String url;
@Value("${appserver1.file}")
private String file;
@Bean
AppServer1 beanExample() {
return new AppServer1(url, file);
}
}
Is there any annotation which can be used with @Configuration to directly identify the config data and used as Autowired.
Thanks.
Upvotes: 1
Views: 2425
Reputation: 16439
First of all, don't use custom YML files as there is an issue in spring boot for custom YML support and it's still not resolved by Spring Team.
Read my answer here about why it doesn't support and also the workaround solution is attached in that answer.
Go for .properties
file for now. Just create a config.properties
file.
appserver1.url=http://localhost:8080/api1
appserver1.file=\\file1.txt
appserver2.url=http://localhost:8081/api2
appserver2.file=\\file2.txt
appserver3.url=http://localhost:8082/api3
appserver3.file=\\file3.txt
Then create your 3 class with same exact name (camelcase) of the field specified in the properties file.
AppServer1.java
@Component
@PropertySource("classpath:config.properties")
@ConfigurationProperties(prefix = "appserver1")
public class AppServer1 {
private String url;
private String file;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
@Override
public String toString() {
return "AppServer1 [url=" + url + ", file=" + file + "]";
}
}
AppServer2.java
@Component
@PropertySource("classpath:config.properties")
@ConfigurationProperties(prefix = "appserver2")
public class AppServer2 {
private String url;
private String file;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
@Override
public String toString() {
return "AppServer2 [url=" + url + ", file=" + file + "]";
}
}
AppServer3.java
@Component
@PropertySource("classpath:config.properties")
@ConfigurationProperties(prefix = "appserver3")
public class AppServer1 {
private String url;
private String file;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
@Override
public String toString() {
return "AppServer3 [url=" + url + ", file=" + file + "]";
}
}
SampleController to test :
@RestController
public class SampleController {
@Autowired
private AppServer1 appServer;
@GetMapping("appserver")
public AppServer1 server() {
return appServer;
}
}
As soon as, you hit the api - http://localhost:8080/appserver
{
"url": "http://localhost:8080/api1",
"file": "\\file1.txt"
}
Upvotes: 0
Reputation: 18899
@PropertySource
will be needed to load the custom yml that you have named config.yml
@ConfigurationProperties
will be needed with a prefix in order to read the correct set of properties inside the yml
@Component
will be needed to make that configuration class be converted into a spring bean which could be autowired
You also need to change the field of the class from filePath
to file
to match the property in your yml. Also change the field URL
to url
, to match again with the property.
@PropertySource("classpath:config.yml")
@ConfigurationProperties(prefix = appserver1)
@EnableConfigurationProperties()
public class AppServer1 {
private String url;
private String file;
public String getUrl() {
return url;
}
public void setUrl(String Url) {
this.url = url;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
}
If you want you can avoid @Component
and use another annotations which is for that reason: Just go to the class where you need to be able to autowire those AppServers and add the following annotation @EnableConfigurationProperties ({AppServer1.class, AppServer2.class, AppServer3.class})
Upvotes: 2