Skip to content

Hướng dẫn sử dụng @ConfigurationProperties

Cấu hình đơn giản

Giả sử, ứng dụng của tôi sẽ yêu cầu có một số giá trị toàn cục, mà thay vì cấu hình ở trong code, tôi muốn lưu nó ở bên ngoài, để tiện thay đổi mỗi khi cần.

Thì tôi sẽ làm như sau, tạo ra một class chứa các thông tin:

@Data // Lombok (Tạo Getter, Setter các thứ)
@Component // Là 1 Spring Bean
// Đánh dấu để lấy config từ trong file loda.yml
// @PropertySource("classpath:loda.yml")
@ConfigurationProperties(prefix = "loda") // Chỉ lấy các config có tiền tố là "loda"
public class LodaAppProperties {
    private String email;
    private String googleAnalyticsId;

    // standard getters and setters
}

Sử dụng @PropertySource để định nghĩa tên của file config. Nếu không có annotation này, Spring sẽ sử dụng file mặc định (classpath:application.yml trong thư mục resources)

Cuối cùng là @ConfigurationProperties, Annotation này đánh dấu class bên dưới nó là properties, các thuộc tính sẽ được tự động nạp vào khi Spring khởi tạo. Lưu ý: các thuộc tính này được xác định bởi prefix=loda. Cái này bạn xem file application.yml ở dưới sẽ hiểu.

Spring sẽ tự tìm các hàm setter để set giá trị cho các thuộc tính này, nên quan trọng là bạn phải tạo ra các setter method. (Ở đây tôi nhường việc đó cho lombok).

Ngoài ra, để chạy được tính năng này, bạn cần kích hoạt nó bằng cách gắn @EnableConfigurationProperties lên một Configuration nào đó. Ở đây tôi gắn lên hàm main luôn.

@SpringBootApplication
@EnableConfigurationProperties
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

Bây giờ, Spring sẽ tự động bind toàn bộ giá trị từ trong file application.yml vào bean LodaAppProperties cho chúng ta. Tạo ra file application.yml tại thư mục resources. Thêm các thông tin chúng ta cần. Chúng ta phải đặt các thuộc tính này sau prefix loda:

loda:
  email: loda.namnh@gmail.com
  googleAnalyticsId: U-xxxxx

Chạy thử

@SpringBootApplication
@EnableConfigurationProperties
public class App implements CommandLineRunner {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    @Autowired LodaAppProperties lodaAppProperties;

    @Override
    public void run(String... args) throws Exception {
        System.out.println("Global variable:");
        System.out.println("\t Email: "+lodaAppProperties.getEmail());
        System.out.println("\t GA ID: "+lodaAppProperties.getGoogleAnalyticsId());
    }
}

Kết quả:

Global variable:
     Email: loda.namnh@gmail.com
     GA ID: U-xxxxx

Bây giờ, ở bất kỳ đâu trong chương trình, khi cần lấy các thông tin config, tôi chỉ cần:

@Autowired LodaAppProperties lodaAppProperties;

Nested Properties

Chúng ta có thể config các thuộc tính bên trong Class kể cả khi nó là ListsMaps hay một class khác.

Bổ sung thêm thuộc tính:

...
@ConfigurationProperties(prefix = "loda") // Chỉ lấy các config có tiền tố là "loda"
public class LodaAppProperties {
    ...
    private List<String> authors;
    private Map<String, String> exampleMap;
}

Sửa file application.yml:

loda:
  email: loda.namnh@gmail.com
  googleAnalyticsId: U-xxxxx
  authors:
    - loda
    - atom
  exampleMap:
    key1: hello
    key2: world

Chạy lại chương trình:

@Override
public void run(String... args) throws Exception {
    System.out.println("Global variable:");
    System.out.println("\t Email: " + lodaAppProperties.getEmail());
    System.out.println("\t GA ID: " + lodaAppProperties.getGoogleAnalyticsId());
    System.out.println("\t Authors: " + lodaAppProperties.getAuthors());
    System.out.println("\t Example Map: " + lodaAppProperties.getExampleMap());
}

Kết quả:

Global variable:
     Email: loda.namnh@gmail.com
     GA ID: U-xxxxx
     Authors: [loda, atom]
     Example Map: {key1=hello, key2=world}