Code ví dụ Spring Boot đọc file properties, @ConfigurationProperties, @PropertySource.
Ở phần này mình sẽ làm ví dụ về các cách đọc thông tin từ file config .properties với Spring Boot.
1. Với các file .properties đơn giản
1.1. Sử dụng annotation @Value
Cách đơn giản nhất là sử dụng annotation @Value
để inject giá trị trong file application.properites
vào thuộc tính của các Spring Bean.
Ví dụ:
message=Default message from application.properties
package stackjava.com.springboothello.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import stackjava.com.springboothello.bean.GlobalConfig; @Controller public class BaseController { @Value("${message}") private String message; }
1.2. Sử dụng annotation @PropertySource để đọc những file .properites tùy chọn.
Ví dụ:
website=stackjava.com facebook=facebook.com/stackjava name=kai
package stackjava.com.springboothello.bean; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @PropertySource("classpath:global.properties") public class GlobalConfig { @Value("${name}") private String name; @Value("${website}") private String website; @Value("${facebook}") private String facebook; // getter / setter }
1.3. Sử dụng annotation @EnableAutoConfiguration
Annotation @EnableAutoConfiguration
sẽ tự động mapping thuộc tính của bean với các giá trị trong file .properties
Ví dụ:
package stackjava.com.springboothello.bean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @ConfigurationProperties @PropertySource("classpath:global.properties") public class GlobalConfig { private String name; private String website; private String facebook; // getter / setter }
2. Đọc các file properties phức tạp
Ví dụ:
#App app.menus[0].title=Home app.menus[0].name=Home app.menus[0].path=/home app.menus[1].title=Login app.menus[1].name=Login app.menus[1].path=/login
Hoặc với file yaml
app: menus: - title: Home name: Home path: / - title: Login name: Login path: /login
@ConfigurationProperties
hỗ trợ cả file.properties
và file.yml
.package stackjava.com.springboothello.bean; import java.util.ArrayList; import java.util.List; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @ConfigurationProperties("app") // prefix app, find app.* values @PropertySource("classpath:menu.properties") public class MenuConfig { private List<Menu> menus = new ArrayList<>(); public List<Menu> getMenus() { return menus; } public void setMenus(List<Menu> menus) { this.menus = menus; } public static class Menu { private String name; private String path; private String title; // getter - setter @Override public String toString() { return "Menu{" + "name='" + name + '\'' + ", path='" + path + '\'' + ", title='" + title + '\'' + '}'; } }
3. Sử dụng Environment
Bạn chỉ cần inject Environment vào các component là có thể lấy các message trong file .properties.
Mặc định Environment lấy message từ trong file application.properties, nếu bạn muốn nó đọc từ cả các file khác thì dùng kèm với @PropertySource
Ví dụ:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @Service public class HelloService { @Autowired Environment env; public void hello() { System.out.println(env.getProperty("message")); } }
4. Validate dữ liệu từ file properties
@ConfigurationProperties
Hỗ trợ validate dữ liệu với javax.validation
Để validate dữ liệu ta sử dụng annotation @Validated
ở đầu class và các annotation validate ở mỗi field ví dụ:
package stackjava.com.springboothello.bean; import javax.validation.constraints.NotEmpty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; @Component @ConfigurationProperties @PropertySource("classpath:global.properties") @Validated public class GlobalConfig { @NotEmpty private String name; private String website; private String facebook; // getter - setter }
Nếu dữ liệu không hợp lệ thì ứng dụng sẽ start failed và thông báo lỗi:
*************************** APPLICATION FAILED TO START *************************** Description: Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under '' to stackjava.com.springboothello.bean.GlobalConfig failed: Property: .name Value: Origin: "name" from property source "class path resource [global.properties]" Reason: must not be empty Action: Update your application's configuration
5. Demo.
File Properties:
message=Default message from application.properties
#App app.menus[0].title=Home app.menus[0].name=Home app.menus[0].path=/home app.menus[1].title=Login app.menus[1].name=Login app.menus[1].path=/login
website=stackjava.com facebook=facebook.com/stackjava name=kai
File Controller:
package stackjava.com.springboothello.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import stackjava.com.springboothello.bean.GlobalConfig; import stackjava.com.springboothello.bean.MenuConfig; @Controller public class BaseController { @Autowired private GlobalConfig globalConfig; @Autowired private MenuConfig menuConfig; @Value("${message}") private String message; @RequestMapping("/") public String index(Model model) { model.addAttribute("name", globalConfig.getName()); model.addAttribute("website", globalConfig.getWebsite()); model.addAttribute("facebook", globalConfig.getFacebook()); model.addAttribute("message", message); model.addAttribute("menus", menuConfig.getMenus()); return "index"; } }
File view:
<html xmlns:th="http://www.thymeleaf.org"> <head> <title>Spring Boot</title> </head> <body> <h1>Spring Boot Properites file</h1> <table> <tr> <td>Name:</td> <td><p th:text="${name}">Default Name</p></td> </tr> <tr> <td>Website:</td> <td><p th:text="${website}">Default Website</p></td> </tr> <tr> <td>Facebook:</td> <td><p th:text="${facebook}">Default Facebook</p></td> </tr> <tr> <td>Message:</td> <td><p th:text="${message}">Default Message</p></td> </tr> Menu: <ul th:if="${menus != null && !menus.empty}"> <li th:each="menu: ${menus}" th:text="${menu}"></li> </ul> </table> </body> </html>
Kết quả:
Okay, Done!
Download code ví dụ trên tại đây.
Code ví dụ Spring Boot đọc file properties, @ConfigurationProperties, @PropertySource, Environment stackjava.com
References: