2009-10-16 28 views
8

Có cách nào để lấy các tệp thuộc tính là các lớp được nhập mạnh không? Tôi đoán có các trình tạo mã nhưng thực hiện nó với chú thích sẽ mát hơn nhiều.Các tệp Java .properties như các lớp được nhập mạnh mẽ

Ý tôi là;

foo.properties file 
keyFoo = valuefoo 
keyBar = valuebar 

có thể với

@properties(file="foo.properties") 
class foo { } 

trở thành

class foo { 
    String getKeyFoo() { } 
    String getKeyBar() { } 
} 

nếu không tôi sẽ bắt đầu một dự án mã nguồn mở cho điều đó?

THÊM VÀO CÂU HỎI;

Hãy nghĩ rằng chúng tôi có tệp foo.properties với giả sử hơn 10 mục nhập; và nghĩ rằng nó được sử dụng như một tệp cấu hình đơn giản. Điều tôi tin là các mục cấu hình này nên được cung cấp như một lớp cấu hình với các phương thức getXXX liên quan đến các phần khác của thiết kế. Sau đó, phần còn lại của hệ thống truy cập cấu hình thông qua lớp được cung cấp thay vì đối phó với các tên khóa và không cần phải bận tâm nơi cấu hình đến. Sau đó, bạn có thể thay thế lớp này bằng một mô hình khi bạn đang thử nghiệm người gọi và sự phụ thuộc vào hệ thống tệp sẽ biến mất. Mặt khác, nó thực sự là tốt đẹp để nhận được tất cả các mục trong một thời trang gõ mạnh mẽ.

Vì vậy, vấn đề này là một vấn đề tạo mã đằng sau hậu trường, nó không liên quan đến thời gian chạy. Nhưng việc tạo mã bằng một cái gì đó bên ngoài thay vì chú thích dường như không tốt cho tôi. Mặc dù tôi không quen thuộc nhiều với chú thích, tôi đoán điều này có thể đạt được (nhưng tôi sẽ nhớ rằng các chú thích không thể tạo ra các lớp như các điểm McDowell)

+1

những gì sẽ là trường hợp sử dụng cho việc này? một ví dụ sẽ là tuyệt vời – Chii

Trả lời

2

Có một somewhat similar project để thực hiện cấu hình dưới dạng tệp được nhập tĩnh. Nó đòi hỏi phải khai báo một giao diện, nhưng nó lấp đầy trong việc thực hiện bản thân:

public interface AppConfig extends Config { 
    long getTimeout(); 
    URL getURL(); 
    Class getHandlerClass(); 
} 
+0

Liên kết đã chết ... – Kukeltje

+0

Khung OWNER cung cấp Cấu hình này, xem http://owner.aeonbits.org/ – vorburger

0

Nếu bạn muốn làm nó tĩnh, tạo mã vấn đề có thể được giải quyết khá dễ dàng (đối với mỗi mục trong tập tin, tạo ra phương thức getXXX mới).

Nhưng nếu bạn muốn điều này trong thời gian chạy, sau đó bạn có vấn đề có phương pháp tham chiếu mã không tồn tại trong thời gian biên dịch; Tôi không nghĩ rằng nó có thể được thực hiện.

(Lưu ý rằng nếu bạn đang tìm kiếm một idead dự án, ngược lại, có một giao diện với phương pháp accessor và chú thích, và một thực hiện tạo ra trong thời gian chạy, dựa trên phương pháp chú thích, có thể được thực hiện.)

+0

Có, nó có thể được thực hiện - Java là một ngôn ngữ rất năng động, và bạn có thể nhổ ra và sửa đổi các lớp theo ý muốn. Câu hỏi đặt ra là "cần bao nhiêu nỗ lực?" –

+0

Tất nhiên, bạn luôn có thể tạo một đối tượng từ tệp conf, nhưng không biết trước các phương thức, bạn sẽ không thể sử dụng nó mà không cần phải phản chiếu hoặc những thứ như thế này, và điều này làm cho điều này trở nên kém thú vị . – penpen

+0

@ Jonathan: IMO, câu hỏi thực sự là "điểm là gì?" kể từ khi @penpen chỉ ra bạn chỉ có thể gọi các phương thức getXXX mới bằng cách sử dụng sự phản chiếu (hoặc từ mã được tạo khác). –

1

chú thích cụ chế biến (apt) không thể sửa đổi các lớp học (mặc dù nó có thể tạo ra những cái mới). Để sửa đổi lớp tại thời gian biên dịch, bạn có thể cần phải chỉnh sửa AST (như Project Lombok không). Cách tiếp cận đơn giản nhất có thể là tạo các lớp và sau đó sử dụng thư viện được tạo ra như là một sự phụ thuộc cho mã khác.

3

Có vô số khung công tác đạt được điều đó cho XML với mức cấu hình khác nhau cần thiết. Một tiêu chuẩn đi kèm với Java là JaxB nhưng nó không phải là chính xác một khuôn khổ duy trì xml một lớp ...

Vấn đề là việc sử dụng tệp thuộc tính sẽ chỉ hoạt động tốt hơn XML (hoặc JSON, ...) trên nhiều nhất các lớp tầm thường.Khi lớp học trở nên phức tạp hơn một chút, tệp thuộc tính sẽ trở thành một cơn ác mộng. Một vấn đề khác là với các lớp tầm thường - không có nhiều sự khác biệt giữa Xml và các thuộc tính.

Điều đó có nghĩa là phạm vi của dự án sẽ khá hạn chế. Chủ yếu hữu ích cho dự án có tải các tệp thuộc tính đơn giản.

Trong ứng dụng lớn, tôi đã làm việc với, đọc mạnh mẽ các tập tin thuộc tính được thực hiện khá thường xuyên bằng cách sử dụng một phương pháp nhà máy đơn giản.

Foo foo = Foo.loadFrom("foo.properties"); 

class Foo { 
    static Foo loadFrom(String fileName) { 
     Properties props = new Properties(); 
     props.load(...); 

     Foo foo = new Foo(); 
     foo.setKeyFoo(props.get("KeyFoo")); 
     ... 
     return foo; 
    } 
    ... 
} 
+0

Có thể hoặc sử dụng sự phản chiếu trong thời gian chạy để tải động một cách linh hoạt: bạn có thể đọc chú thích (có sẵn từ Lớp, Phương pháp và Các đối tượng trường) và nhận/thiết lập các thuộc tính động (bằng cách sử dụng các bean phổ biến apache có thể giúp bạn ở đó). Cố gắng giữ cho nó đơn giản mặc dù nếu bạn có cấu hình nhỏ. Đối với tải cấu hình, Xml mang đến cho bạn cấu trúc, xác thực và tài liệu (trong XSD), ... – vdr

+0

+1 cho JAXB. Tôi đã chuyển sang nó cho cấu hình của tôi. Cũng buộc tôi phải dọn dẹp sự phân biệt cấu hình/trạng thái của mình. –

1

Something như JFig (xấu xí IMO), Commons Configuration hoặc EasyConf?

+0

OT: Thú vị: Mặc dù có nhiều thư viện để đọc các thuộc tính, nhưng không có thư viện nào cho phép lặp lại theo thứ tự - vì vậy tôi không thể lấy các thuộc tính theo thứ tự chúng được định nghĩa trong tệp. Vì vậy, tôi đã mở rộng các thuộc tính và giao tất cả các phương thức Map cho một ListOrderedMap. –

+0

Giải pháp thay thế mới cho JFig: https://github.com/sofdes/config-generation-maven-plugin – user1016765

0

OP muốn ánh xạ tệp thuộc tính vào API Java sao cho mỗi thuộc tính được đặt tên trong tệp tương ứng với phương thức getter có tên tương tự trong API. Tôi đoán rằng một ứng dụng sau đó sẽ sử dụng API này để nhận các giá trị thuộc tính mà không cần phải sử dụng các chuỗi tên thuộc tính.

Vấn đề khái niệm là tệp thuộc tính về cơ bản không phải là thực thể được nhập tĩnh. Mỗi khi ai đó chỉnh sửa tệp thuộc tính, họ có thể thêm thuộc tính mới và do đó thay đổi "loại" của tệp thuộc tính ... và bằng cách ngụ ý, chữ ký của API tương ứng. Nếu chúng tôi kiểm tra rằng không có bất động sản bất ngờ khi ứng dụng Java đã tải tệp thuộc tính, thì chúng tôi đã có kiểm tra loại động rõ ràng. Nếu chúng tôi không kiểm tra các thuộc tính không mong muốn (ví dụ: bị đặt tên sai), chúng tôi có một nguồn lỗi. Mọi thứ trở nên lộn xộn hơn nếu bạn muốn các loại giá trị thuộc tính là một cái gì đó khác với một String.

Cách duy nhất bạn có thể làm điều này đúng là phát minh khái niệm lược đồ cho tệp thuộc tính đã chỉ định tên thuộc tính và loại giá trị thuộc tính. Sau đó, triển khai trình chỉnh sửa tệp thuộc tính để đảm bảo rằng người dùng không thể thêm các thuộc tính xung đột với lược đồ. Và tại thời điểm này, chúng ta nên nhận ra rằng một giải pháp tốt hơn là sử dụng XML làm đại diện tệp thuộc tính, một trình soạn thảo XML được định hướng lược đồ để chỉnh sửa các tệp thuộc tính và JAXP hoặc một cái gì đó như nó để ánh xạ tệp thuộc tính tới các API Java .

+0

Tôi không hiểu chính xác ý bạn là gì "và do đó thay đổi" loại "của tệp" ... Nhưng Tôi đoán những gì bạn đang lo lắng là các loại dữ liệu khác nhau trong tập tin? Nếu vậy; đối với trường hợp này, các kiểu trả về luôn là String ... Vì vậy, việc thêm một mục mới vào tệp sẽ làm cho trình tạo ra tạo phương thức truy cập mới ... – erdogany

+0

@erdogany: Không. Tôi đang nói về tên của các thuộc tính thay đổi. Nếu bạn đọc câu hỏi, bạn sẽ thấy rằng OP muốn ánh xạ từng thuộc tính đến một phương thức getter riêng biệt có tên bắt nguồn từ tên thuộc tính. –

1

Một cách khác là sử dụng khung ràng buộc dữ liệu để thực hiện việc này. Ngay cả một cái dường như không hỗ trợ trực tiếp có thể hoạt động: ví dụ: Jackson Bộ xử lý JSON sẽ cho phép điều này được thực hiện bằng một cái gì đó như:

ObjectMapper m = new ObjectMapper(); MyBean bean = m.convertValue (thuộc tính, MyBean.class); // (lưu ý: yêu cầu mã mới nhất từ ​​thân cây; nếu không cần viết trước, hãy đọc lại)

hoạt động miễn là các mục trong Bản đồ thuộc tính khớp với thuộc tính lôgic hợp lý và giá trị chuỗi có thể được chuyển đổi thành phù hợp với giá trị cơ bản.

0

Tôi nghĩ rằng điều này sẽ giải quyết vấn đề của bạn Tôi đã viết trên khuôn khổ tài sản này cho năm ngoái. Nó sẽ cung cấp nhiều cách để tải các thuộc tính, và chúng cũng được đánh mạnh.

Có một cái nhìn tại http://sourceforge.net/projects/jhpropertiestyp/

Nó là nguồn mở và ghi chép đầy đủ

Dưới đây là mô tả ngắn gọn của tôi từ SourceForge:

JHPropertiesTyped will give the developer strongly typed properties. Easy to integrate in existing projects. Handled by a large series for property types. Gives the ability to one-line initialize properties via property IO implementations. Gives the developer the ability to create own property types and property io's. Web demo is also available, screenshots shown above. Also have a standard implementation for a web front end to manage properties, if you choose to use it. 

Complete documentation, tutorial, javadoc, faq etc is a available on the project webpage. 
Các vấn đề liên quan