2012-07-08 22 views
23

Tôi có thể chỉ nhìn sai hướng nhưng tôi thấy tài liệu JSE về xử lý chú thích rất ... thưa thớt. Tôi muốn viết một bộ xử lý chú thích xử lý các trường String có chú thích và các biến cục bộ để thay thế chúng bằng một biểu thức String được tính toán. Điều này không nên quá phức tạp nhưng tôi khá mất trong Javadoc cho javax.annotation.processing.Làm thế nào để viết một bộ xử lý chú thích Java?

EDIT: Tôi cần xử lý chú thích tại thời gian biên dịch vì tôi muốn sửa đổi mã được tạo. Nó nên thay thế các biểu thức String không đổi có chú thích bằng biểu thức String được tính toán.

+0

Đồng ý, điểm vào của tôi là hướng dẫn này: http://tutorials.jenkov.com/java-reflection/annotations.html –

+2

Bạn có muốn xử lý chú thích tại thời gian biên dịch hay thời gian chạy không? Lưu ý rằng các chú thích trên các biến cục bộ có hiệu quả vô dụng do giới hạn javac ngớ ngẩn. –

+0

Tôi muốn xử lý chúng tại thời gian biên dịch, do đó, điều này rõ ràng sẽ chỉ hoạt động cho các biểu thức chuỗi không đổi. –

Trả lời

14

Điều này không thể thực hiện được với bộ xử lý chú thích thời gian biên dịch. Biên dịch các bộ xử lý chú thích thời gian chỉ có thể tạo ra các tệp mới (và các lớp) mà chúng không thể sửa đổi các lớp hiện có. Bạn có thể thực hiện sự phản chiếu trong thời gian chạy nhưng nghiêm túc nói rằng bạn không được gọi là xử lý chú thích. Ngoài ra, bạn sẽ không có quyền truy cập vào các biến cục bộ.

Nếu bạn đang tìm kiếm trên làm thế nào để viết một bộ xử lý chú thích thời gian biên dịch kiểm tra https://github.com/pellaton/spring-configuration-validation-processor

+0

Về mặt lý thuyết, bạn có thể sử dụng bộ xử lý chú thích + Apache BCEL (hoặc một cái gì đó tương tự) để sửa đổi tệp .class gốc. Nhưng điều đó nghe có vẻ lộn xộn. – vanza

+0

Err ... cái gì? Tôi không thể sửa đổi mã nguồn trước khi biên dịch bằng cách sử dụng khung chú thích? –

+1

Tôi đã xem mã được liên kết. Rõ ràng nó không tạo ra mã, nó chỉ xác nhận nó.Tôi đã hy vọng tôi có thể sửa đổi Abstract Syntax Tree trước bước tạo mã thực tế. –

4
+0

Tôi đã xem xét Javassist và ASM. Có lẽ họ sẽ làm công việc, nhưng họ là về thao tác mã byte. Tôi rất thích sử dụng một công cụ cho phép tôi thao tác Cây Cú pháp Trừu tượng. Thao tác mã byte sẽ chỉ là phương sách cuối cùng của tôi. –

+0

OK, sau khi điều tra các tùy chọn, có vẻ như thao tác mã byte là lựa chọn khả thi duy nhất còn lại. Thách thức tiếp theo là tích hợp điều này vào một bản xây dựng Maven - không chỉ cho tôi, mà còn cho người dùng thư viện của tôi nữa. –

+0

Hmm ... thao tác AST sẽ là _my_ last resort :) –

8

Hai công cụ thực hiện điều này là Project LombokDuctileJ. Cả hai công cụ này đều tồn tại vào thời điểm câu hỏi ban đầu được hỏi; các công cụ bổ sung giờ đây chắc chắn tồn tại.

Ý tưởng chính là viết bộ xử lý chú thích đi qua và sửa đổi AST của chương trình (cây cú pháp trừu tượng) trong khi biên dịch, trước khi tạo mã. Trình biên dịch sẽ không thay đổi mã nguồn trên đĩa, nhưng tệp .class được tạo sẽ phản ánh những thay đổi mà bộ xử lý chú thích của bạn tạo ra.

Bạn có thể điều chỉnh một trong các công cụ này cho phù hợp với nhu cầu của mình hoặc bạn có thể triển khai công cụ của riêng mình lấy cảm hứng từ kỹ thuật triển khai của chúng.

Xử lý thời gian biên dịch có hai ưu điểm so với xử lý tệp lớp. Một là trình biên dịch thường có nhiều thông tin hơn là có sẵn từ mã được biên dịch. Khác là mọi thứ xảy ra trong một bước, trong quá trình biên dịch, thay vì yêu cầu nhà phát triển chạy một công cụ riêng biệt để ghi lại các tệp .class sau khi biên dịch.

+0

chắc chắn và đáng nhắc đến là cả hai đều sử dụng hack để sửa đổi AST, khai thác lỗi trong bộ xử lý chú thích hiện tại trong Java, sử dụng các API javac nội bộ có thể cố định/loại bỏ trong một số JDK trong tương lai (mà đi xuống như một bất lợi lớn đối với tôi). –

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