2014-10-01 17 views
26

Có thể có các trường bất biến (cuối cùng) với chú thích @ConfigurationProperties của Spring Boot không? Ví dụ dưới đâyKhông thể thay đổi @ConfigurationProperties

@ConfigurationProperties(prefix = "example") 
public final class MyProps { 

    private final String neededProperty; 

    public MyProps(String neededProperty) { 
    this.neededProperty = neededProperty; 
    } 

    public String getNeededProperty() { .. } 
} 

phương pháp tiếp cận tôi đã cố gắng cho đến nay:

  1. Tạo một @Bean của lớp MyProps với hai cấu trúc
    • Cung cấp hai cấu trúc: trống và với neededProperty luận
    • Các đậu được tạo với new MyProps()
    • Kết quả trong lĩnh vực này null
  2. Sử dụng @ComponentScan@Component để cung cấp đậu MyProps.
    • Kết quả trong BeanInstantiationException ->NoSuchMethodException: MyProps.<init>()

Cách duy nhất tôi đã nhận nó làm việc bằng cách cung cấp getter/setter cho từng lĩnh vực phi chính thức.

+1

Theo hiểu biết của tôi, những gì bạn đang cố gắng để làm sẽ không làm việc ra khỏi hộp. – geoand

+0

Thật đáng buồn.Tất nhiên, tôi luôn có thể làm điều đó với Spring đơn giản bằng cách sử dụng các tham số constructor với chú thích '@ Value'. Tuy nhiên, nó sẽ là tốt đẹp nếu Spring Boot cũng hỗ trợ điều này. – RJo

+0

Tôi lấy một đỉnh nhỏ ở mã nguồn, nhưng nó không phức tạp để hỗ trợ một cái gì đó giống như những gì bạn đang yêu cầu. Tất nhiên tôi không có chuyên gia về nội bộ mùa xuân vì vậy tôi có thể thiếu một cái gì đó rõ ràng – geoand

Trả lời

10

Tôi phải giải quyết vấn đề đó rất thường xuyên và tôi sử dụng một cách tiếp cận khác một chút, cho phép tôi sử dụng các biến số final trong một lớp học.

Trước hết, tôi giữ tất cả cấu hình của mình ở một nơi duy nhất (lớp), gọi là ApplicationProperties. Lớp đó có chú thích @ConfigurationProperties với tiền tố cụ thể. Nó cũng được liệt kê trong chú thích @EnableConfigurationProperties đối với lớp cấu hình (hoặc lớp chính).

Sau đó, tôi cung cấp ApplicationProperties làm đối số hàm tạo và thực hiện gán cho trường final bên trong một hàm tạo.

Ví dụ:

chính lớp:

@SpringBootApplication 
@EnableConfigurationProperties(ApplicationProperties.class) 
public class Application { 
    public static void main(String... args) throws Exception { 
     SpringApplication.run(Application.class, args); 
    } 
} 

ApplicationProperties lớp

@ConfigurationProperties(prefix = "myapp") 
public class ApplicationProperties { 

    private String someProperty; 

    // ... other properties and getters 

    public String getSomeProperty() { 
     return someProperty; 
    } 
} 

Và một lớp học với tính chất cuối cùng

@Service 
public class SomeImplementation implements SomeInterface { 
    private final String someProperty; 

    @Autowired 
    public SomeImplementation(ApplicationProperties properties) { 
     this.someProperty = properties.getSomeProperty(); 
    } 

    // ... other methods/properties 
} 

Tôi thích phương pháp này vì nhiều lý do khác nhau, ví dụ: nếu tôi phải thiết lập nhiều thuộc tính hơn trong một hàm tạo, danh sách các đối số hàm tạo của tôi không phải là "rất lớn" vì tôi luôn có một đối số (ApplicationProperties trong trường hợp của tôi); nếu có nhu cầu bổ sung thêm final tài sản, nhà xây dựng của tôi vẫn như cũ (chỉ có một đối số) - đó có thể làm giảm số thay đổi ở nơi khác, vv

Tôi hy vọng rằng sẽ giúp

+1

Đó là rất nhiều đĩa nồi hơi so với chỉ sử dụng @Value –

+0

Đây là [tag: Java]. Thêm boilerplate có nghĩa là mã tốt hơn – Clijsters

+0

@Clijsters Tôi thành thật không thể nói nếu bạn đang được facetious nhưng tôi có nghĩa là, nó không hoàn toàn đúng, nhưng nó không xa một trong hai! –

Các vấn đề liên quan