2015-03-22 36 views
6

Tôi có một loạt các hằng số trong suốt mã của tôi cho các thuộc tính có thể điều chỉnh khác nhau của hệ thống của tôi. Tôi đang di chuyển tất cả chúng đến một tệp trung tâm .properties. Giải pháp hiện tại của tôi là phải có một đơn Properties.java mà tĩnh tải file .properties và thấy nhiều phương pháp getter khác nhau như thế này:Tiêm các hằng số thông qua Chú thích tùy chỉnh

public class Properties { 
    private static final String FILE_NAME = "myfile.properties"; 
    private static final java.util.Properties props; 

    static { 
     InputStream in = Properties.class.getClassLoader().getResourceAsStream(
       FILE_NAME); 
     props = new java.util.Properties(); 
     try { 
      props.load(in); 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public static String getString(Class<?> cls, String key) { 
     return props.getProperty(cls.getName() + '.' + key); 
    } 

    public static int getInteger(Class<?> cls, String key) { 
     return Integer.parseInt(getString(cls, key)); 
    } 

    public static double getDouble(Class<?> cls, String key) { 
     return Double.parseDouble(getString(cls, key)); 
    } 
} 

Vấn đề duy nhất với điều đó là đối với mỗi hằng số mà tôi nhận được từ tập tin này, tôi có một số boilerplate:

private final static int MY_CONSTANT = Properties.getInteger(
    ThisClass.class, "MY_CONSTANT"); 

Tôi không nghĩ rằng tôi muốn sử dụng Mùa xuân hoặc tương tự như vậy dường như thậm chí còn nhiều lò hơi hơn. Tôi đã hy vọng sử dụng chú thích tùy chỉnh để giải quyết vấn đề. Tôi đã tìm thấy this tutorial, nhưng tôi thực sự không thể phân loại cách lấy chức năng mà tôi muốn xử lý chú thích. Các tài liệu Java thậm chí còn ít hữu ích hơn. Điều này nên là một điều tôi có thể làm tại thời gian biên dịch, mặc dù. Tôi biết tên của lớp và lĩnh vực.

Những gì tôi đang suy nghĩ là một cái gì đó như thế này:

@MyAnnotation 
private static final int MY_CONSTANT; 

Bất cứ ai cũng biết làm thế nào tôi sẽ đi về việc này hoặc ít nhất là thực hành tốt nhất cho những gì tôi muốn làm gì?

+0

Tại sao bạn cho rằng tải mã tấm nồi hơi của nó? wont thêm chú thích sẽ thêm vào nó? – SMA

+0

Những thứ đó thực sự là hằng số? Hoặc nhiều hơn như các mục cấu hình? Nếu chúng là cấu hình, nó thực sự cần thiết để viết chúng như hằng số? Bởi vì công cụ sửa đổi 'final' sẽ mất đi ý nghĩa của nó (tôi thậm chí không chắc chắn rằng sự phản chiếu có thể gán một giá trị cho một trường' final'). Nếu chúng chỉ là cấu hình, thì tại sao bạn không sử dụng một khung cấu hình để giảm bớt công việc của bạn (như [commons-configuration] (https://commons.apache.org/proper/commons-configuration/) hoặc [typesafe's config] (https://github.com/typesafehub/config))? Nếu chúng là hằng số, tại sao cần phải có khả năng "sửa đổi" chúng trong mỗi lần chạy? –

+0

Ngoài ra, bạn không đóng 'InputStream' trong khối' try-catch-finally' của bạn. Bạn nên thử và làm điều đó. –

Trả lời

2

Trước hết, bạn không nên làm điều đó. Đó là thực tế, nhưng quá hacky và nếu bạn đã bao giờ muốn viết một bài kiểm tra bằng cách sử dụng các cài đặt khác nhau, bạn sẽ gặp vấn đề. Hơn nữa, không ai sẽ hiểu nó hoạt động như thế nào.

Bộ xử lý chú thích có thể không làm gì cho bạn. Một bộ xử lý kiểu Lombok-hack có thể. Bạn muốn chắc

@MyAnnotation 
private static final int MY_CONSTANT; 

công việc như

private final static int MY_CONSTANT = 
    Properties.getInteger(ThisClass.class, "MY_CONSTANT"); 

Khái niệm ban đầu không biên dịch (do biến thức chưa được khởi tạo), nhưng nó phân tích tốt và Lombok có thể làm công việc của mình. Có đã một cái gì đó liên quan có:

  • @Value thay đổi bổ để final private
  • @UtilityClass làm cho tất cả các lĩnh vực static

Vì vậy, trên thực tế, bạn có thể viết chỉ

@MyAnnotation 
int MY_CONSTANT; 

và để chú thích của mình cũng thay đổi các modifier. Tôi muốn xem xét các trình xử lý eclipsejavac cho @UtilityClass, tôi đoán tất cả những gì bạn cần là tạo trình khởi tạo (đó là một số công việc khá phức tạp vì nó phức tạp).

Tôi không nghĩ Lombok bản thân sẽ thực hiện bất cứ lúc nào này sớm, vì

  • tất cả các static cụ này là không thể kiểm chứng và phong cách chủ yếu là xấu
  • và không phải ai cũng muốn điều này trong mã của họ
  • nó không phải là nhiều boilerplate
  • nó cũng kỳ diệu đề cập đến lớp Properties, nhưng điều này có thể được giải quyết thông qua configuration

nhưng tôi đoán rằng đóng góp có thể được chấp nhận.

1

Thực ra, không rõ lý do tại sao và bạn muốn lưu trữ những gì.

Khi tôi đặt lại chính xác, bạn muốn sử dụng loại chú thích đặc biệt để tự động gán giá trị cho các số static final từ một số tệp properties. Unfortunatelly nó là không thể mà không có hack đặc biệt. Và chú thích không có gì để làm với điều này.

Lý do là các trường final phải được khởi tạo và đó là yêu cầu của trình biên dịch. Không có chú thích đặc biệt trong java sẽ cung cấp cú pháp cú pháp như bạn muốn.

Nhưng nếu bạn nhấn mạnh về vấn đề này có hai cách:

  1. Extrim cách. Bắt đầu tất cả trường thuộc tính với giá trị mặc định. Sau đó, sử dụng this hack trong một số phần static init khởi tạo giá trị này bằng cách sử dụng cơ chế reflection và bạn mã hóa thông qua giá trị đọc từ properties.

  2. Ít cách xa hơn: từ chối yêu cầu final công cụ sửa đổi cho các trường thuộc tính và chỉ sử dụng reflection điền vào các giá trị trường này.

Ngoài ra, theo những cách này, bạn có thể sử dụng chú thích. Nhưng bạn sẽ phải giải quyết các vấn đề kỹ thuật sau đây:

1) Tìm tất cả các trường trong tất cả các lớp trong classpath, được chú thích với bạn đặc biệt annotation. Xem xét: Get all of the Classes in the ClasspathGet list of fields with annotation, by using reflection

2) Buộc lớp Properties của bạn sẽ được khởi tạo trong tất cả các khả năng nhập điểm của ứng dụng của bạn. Trong phần tĩnh trong lớp này, bạn sẽ tải tệp thuộc tính của bạn và sau đó sử dụng phương thức (1) với sự phản chiếu và trình nạp lớp, gán các giá trị cho tất cả các hằng số.

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