Sau một số cuộc điều tra, tôi đã đi đến kết luận rằng cách tiếp cận sau đây có vẻ là tốt nhất.
some / subpackage / Util.groovy
@GrabResolver(name = 'nexus', root = 'https://local-nexus-server:8443/repository/maven-public', m2Compatible = true)
@Grab('com.google.errorprone:error_prone_annotations:2.1.3')
@Grab('com.google.guava:guava:23.0')
@GrabExclude('com.google.errorprone:error_prone_annotations')
import com.google.common.base.Strings
class Util {
void msg(int a, String b, Map c) {
println 'Message printed by msg method inside Util.groovy'
println "Print 5 asterisks using the Guava dependency ${Strings.repeat("*", 5)}"
println "Arguments are a=$a, b=$b, c=$c"
}
}
example.groovy
#!/usr/bin/env groovy
Class clazz = new GroovyClassLoader().parseClass("${new File(getClass().protectionDomain.codeSource.location.path).parent}/some/subpackage/Util.groovy" as File)
GroovyObject u = clazz.newInstance()
u.msg(1, 'b', [a: 'b', c: 'd'])
Để chạy example.groovy
tập lệnh, hãy thêm nó vào đường dẫn hệ thống của bạn và nhập từ bất kỳ thư mục nào:
example.groovy
Kịch bản in:
Message printed by msg method inside Util.groovy
Print 5 asterisks using the Guava dependency *****
Arguments are a=1, b=b, c=[a:b, c:d]
Ví dụ trên đã được thử nghiệm trong môi trường sau: Groovy Version: 2.4.13 JVM: 1.8.0_151 Vendor: Oracle Corporation OS: Linux
Ví dụ minh họa điều sau:
- Cách sử dụng một
Util
lớp bên trong một tập lệnh thú vị.
- Một
Util
lớp gọi Guava
thư viện của bên thứ ba bằng cách bao gồm nó dưới dạng Grape
phụ thuộc ( @Grab('com.google.guava:guava:23.0')
).
- Các
Util
lớp có thể nằm trong một thư mục con.
- Truyền đối số cho một phương thức trong
Util
lớp.
Nhận xét / đề xuất bổ sung:
- Luôn sử dụng một lớp linh hoạt thay vì tập lệnh linh hoạt cho chức năng có thể tái sử dụng trong các tập lệnh linh hoạt của bạn. Ví dụ trên sử dụng lớp Util được định nghĩa trong tệp Util.groovy. Việc sử dụng các tập lệnh linh hoạt cho chức năng có thể tái sử dụng là một vấn đề. Ví dụ: nếu sử dụng một tập lệnh Groovy thì lớp Util sẽ phải được khởi tạo ở cuối tập lệnh với
new Util()
, nhưng quan trọng nhất là nó sẽ phải được đặt trong một tệp có tên bất kỳ thứ gì ngoại trừ Util.groovy. Tham khảo Scripts so với các lớp để biết thêm chi tiết về sự khác biệt giữa các tập lệnh Groovy và các lớp groovy.
- Trong ví dụ trên, tôi sử dụng đường dẫn
"${new File(getClass().protectionDomain.codeSource.location.path).parent}/some/subpackage/Util.groovy"
thay vì "some/subpackage/Util.groovy"
. Điều này sẽ đảm bảo rằng Util.groovy
tệp sẽ luôn được tìm thấy liên quan đến vị trí của tập lệnh groovy ( example.groovy
) chứ không phải thư mục làm việc hiện tại. Ví dụ: sử dụng "some/subpackage/Util.groovy"
sẽ dẫn đến tìm kiếm tại WORK_DIR/some/subpackage/Util.groovy
.
- Tuân theo quy ước đặt tên lớp Java để đặt tên cho các tập lệnh khó hiểu của bạn. Cá nhân tôi thích một độ lệch nhỏ trong đó các chữ viết bắt đầu bằng một chữ cái thường thay vì viết hoa. Ví dụ,
myScript.groovy
là một tên tập lệnh và MyClass.groovy
là một tên lớp. Việc đặt tên my-script.groovy
sẽ dẫn đến lỗi thời gian chạy trong một số trường hợp nhất định vì lớp kết quả sẽ không có tên lớp Java hợp lệ.
- Trong thế giới JVM nói chung, chức năng liên quan được đặt tên là JSR 223: Scripting cho Java . Đặc biệt, chức năng được đặt tên là cơ chế tích hợp Groovy . Trên thực tế, cách tiếp cận tương tự có thể được sử dụng để gọi bất kỳ ngôn ngữ JVM nào từ bên trong Groovy hoặc Java. Một số ví dụ đáng chú ý về các ngôn ngữ JVM như vậy là Groovy, Java, Scala, JRuby và JavaScript (Rhino).