2010-09-02 63 views
5

Đây là câu hỏi: Tôi có phương thức digest(byte[] data). Nó nên là riêng tư, bởi vì chúng tôi thực sự không cần nó bên ngoài một lớp học, tuy nhiên tôi sẽ không chết nếu tôi làm cho nó công khai, nếu nó giúp.
Câu hỏi đặt ra là: có thể tôi bằng cách nào đó đính kèm kẻ đánh chặn vào nó? Cái này là nó không được gọi như getBean('MyBean').digest(), nó được gọi thông qua getBean('MyBean').sign(data) nơi dấu là smth nhưPhương pháp đánh chặn theo phương pháp riêng

public byte[] sign(byte[] data){ 
    ... 
    b = digest(data); 
    ... 
    return signature; 
} 

Thx.

+0

Tôi đã cố gắng định dạng mã của bạn, nhưng nó vẫn là bất hợp pháp. Vui lòng dán chính xác. – Bozho

Trả lời

3

Ngay cả khi phương thức được công khai, Spring không thể chặn cuộc gọi phương thức được tạo từ bên trong đối tượng chứa phương thức. Để đạt được điều này, bạn sẽ phải sử dụng AspectJ.

+0

Đúng, Spring AOP hoạt động với proxy động, nghĩa là bạn chỉ có thể chặn các phương thức được hiển thị trong giao diện và khi proxy có thể ủy quyền trực tiếp cho phương thức được phơi sáng. – nkr1pt

+1

xem http://forum.springsource.org/archive/index.php/t-34372.html – Cid54

+1

Đây chỉ là trường hợp đối với proxy động JDK. Spring AOP cũng có thể làm việc với các proxy lớp con của CGLIB, trong trường hợp này, việc tự gọi các phương thức công cộng hoạt động tốt. – skaffman

1

Sắp xếp đầy đủ AspectJ voodoo, bạn cần phải thực hiện phương thức chặn của mình public. Nếu bạn không muốn hiển thị phương thức digest() của bean của mình là public, nhưng vẫn muốn áp dụng trình chặn, thì tôi khuyên bạn nên tái cấu trúc mã của bạn để trích xuất logic phân loại ra thành một lớp riêng biệt thực hiện giao diện thông báo mới và áp dụng đánh chặn cho điều đó.

Đó là một chút vụng về, nhưng nó buộc bạn phải tách mối quan tâm của bạn, đó không phải là điều xấu.

0

Một cách khác để đạt được những gì bạn muốn là tạo ra một lớp phân hủy và ngăn chặn các cuộc gọi đến nó tiêu hóa() phương pháp:

public interface Digester { 
    public Foo digest(byte[] data); 
} 

class DigesterImpl implements Digester { 
    public Foo digest(byte[] data) {...} 
} 

Sau đó trong mã mùa xuân của bạn, bạn tiêm một DigesterImpl proxy đến lớp và cuộc gọi của bạn nó:

private final Digester digester; 

MyClass(Digester digester) { 
    this.digester = digester; 
} 

public byte[] sign(byte[] data){ 
    ... 
    b = digester.digest(data); 
    ... 
    return signature; 
} 
0

điều quan trọng phải hiểu ở đây là khi sử dụng Aspect lập trình phương pháp kêu gọi rằng tham chiếu đối tượng sẽ được các cuộc gọi trên proxy, và như proxy như vậy sẽ có thể uỷ thác cho tất cả các đánh chặn (a dvice) có liên quan đến cuộc gọi phương thức cụ thể đó. Tuy nhiên, một khi cuộc gọi cuối cùng đã đến đối tượng đích, bất kỳ phương thức nào có thể tự thực hiện, chẳng hạn như Digest (Dữ liệu), sẽ được gọi ra khỏi tham chiếu này, chứ không phải proxy.

Điều này có ý nghĩa quan trọng. Nó có nghĩa là tự gọi sẽ không dẫn đến lời khuyên kết hợp với một lời gọi phương thức nhận được một cơ hội để thực thi. Nhưng có một cách để làm điều đó:

public byte[] sign(byte[] data){ 
    ... 
    b = (Digester)AopContext.currentProxy()).Digest(Data); 
    ... 
    return signature; 
} 

này hoàn toàn cặp mã của bạn để Spring AOP, và nó làm cho lớp tự nhận thức được thực tế là nó đang được sử dụng trong một bối cảnh AOP, mà bay khi đối mặt với AOP.

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