2013-10-23 32 views
6

Vào mùa xuân 3 Spel, #this#root đã được giới thiệu.#root và #this in Spel

Biến #root luôn được xác định và đề cập đến ngữ cảnh gốc đối tượng. Mặc dù #this này có thể thay đổi khi các thành phần của biểu thức được đánh giá là , nhưng #root luôn đề cập đến gốc.

Tôi đã trải qua tài liệu, nhưng tôi vẫn không hiểu ý nghĩa của #root (không có ví dụ). Có thể ai đó xin vui lòng cho tôi một ví dụ?

Trả lời

7

Hãy nói rằng chúng ta có đoạn mã sau đây, mà điền vào một danh sách với một số số nguyên tố và định nghĩa nó như là một biến trong một bối cảnh SpEL:

// create an array of integers 
List<Integer> primes = new ArrayList<Integer>(); 
primes.addAll(Arrays.asList(2,3,5,7,11,13,17)); 

// create parser and set variable 'primes' as the array of integers 
ExpressionParser parser = new SpelExpressionParser(); 
StandardEvaluationContext ctx = new StandardEvaluationContext(); 
ctx.setVariable("primes", primes); 

Bây giờ, nếu chúng ta muốn thu hẹp danh sách và nhận được tất cả các số nguyên tố> 10, chúng tôi có thể sử dụng toán tử lựa chọn ?[]. Tuyên bố sẽ là câu trả lời này:

Expression expression = parser.parseExpression("#primes.?[#this>10]"); 
List<Integer> primesGreaterThanTen = (List<Integer>) expression.getValue(ctx); 

Như bạn có thể thấy, biểu thức cần đánh giá là #primes.?[#this > 10]. Làm thế nào nó hoạt động ?

  • #primes đề cập đến danh sách primes.
  • Toán tử lựa chọn ?[] khớp với mọi đối tượng i trong danh sách primeskhông phải là rỗng và khớp với tiêu chí được đưa ra trong dấu ngoặc đơn. Trong ví dụ của chúng tôi, tiêu chí là #this > 10. #this dùng để chỉ đối tượng đánh giá hiện tại, trong ví dụ của chúng tôi sẽ là đối tượng từ danh sách đang được kiểm tra tại thời điểm này cho không-null và> 10.

Kết quả từ việc đánh giá sẽ là một danh sách, bao gồm:

[11, 13, 17] 

Một SpEL bối cảnh có thể có một biến #root. Chúng ta hãy có lớp đơn giản này:

public class SomeCustomObject { 
    public int stringLength(String input) { 
     if (input == null) return 0; 
     return input.length(); 
    } 
} 

và xác định một thể hiện của SomeCustomObject của chúng tôi là biến #root.

SomeCustomObject someObject = new SomeCustomObject(); 
context.setRootObject(someObject); 

Điều này sẽ tạo đối tượng gốc cho ngữ cảnh SpEL.

Ví dụ đơn giản với biến số #root.

String name = "kocko"; 
ctx.setVariable("name", kocko); 
String statement = "#root.stringLength(#kocko) == 5"; 
Expression expression = parser.parseExpression(statement); 

boolean result = expression.getValue(context, Boolean.class); 

Biến số result sẽ được đánh giá là true.

Sức mạnh của #root là gì?

Thông qua một đối tượng gốc đơn lẻ, bạn có thể hiển thị môi trường tùy chỉnh toàn diện cho các biểu thức của mình, ví dụ phương thức và/hoặc biến số tiện ích tùy chỉnh. Thông tin

thêm:

1

Đối tượng #this thay đổi liên quan đến một phần của biểu thức trong một cái gì đó giống như một chiếu bộ sưu tập, nhưng đối tượng #root không.

Vì vậy, nếu trong hoàn cảnh của bạn, bạn có hai biến: một danh sách các số myNumbers và một số duy nhất maxNumber, bạn có thể tạo ra một dự báo trong danh sách đó với một biểu thức SpEL như:

myNumbers.?[#this lt #root.maxNumber] 

Trong chiếu biểu thức (bên trong dấu ngoặc vuông), đối tượng #this là mục trong bộ sưu tập đang được kiểm tra để xem nó có vượt qua bộ lọc hay không, trong khi đối tượng #root vẫn là các biến trong ngữ cảnh chung.

Nếu bạn có một danh sách của một đối tượng thú vị hơn, như trong Collection Selection documentation example:

Members.?[Nationality == 'Serbian'] 

That "Quốc tịch" là liên quan đến #this, đối tượng thành viên. Nếu bạn muốn so sánh với một biến bối cảnh gốc thay vì một chuỗi chữ, bạn sẽ cần phải làm:

Members.?[Nationality == #root.searchedForNationality] 

Nếu bạn đã chỉ cố gắng [Nationality == searchedForNationality] nó sẽ không làm việc vì searchedForNationality không phải là một phần của thành viên đối tượng, nhưng một biến trên đối tượng gốc. Bạn cần sử dụng #root để đủ điều kiện vì các tham chiếu không đủ tiêu chuẩn mặc định có liên quan đến đối tượng #this.

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