2011-11-01 39 views
5

Tôi đang chơi với Spring AOP.Mùa xuân AOP tạo thêm đậu

Đây là một lớp đơn giản

public class CModel extends Car { 
    private double torqueMeasure = 1; 

    public CModel() { 
     System.out.println(" C-Model constructor");   
    } 
} 

Và mùa xuân cấu hình là như thế này

<aop:config> 
    <aop:aspect ref="audit"> 
     <aop:before pointcut="execution(* com.test.main..*(..))" method="firstControl"/> 
      ... 
    </aop:aspect> 
</aop:config> 

Ok bây giờ; khi tôi thêm aop: config và chặn CModel thì Spring gọi hàm khởi tạo CModel hai lần. Nó có nghĩa là Spring tạo ra 2 đối tượng CModel, đúng không?

Nếu tôi xóa cấu hình AOP thì Spring chỉ tạo một đối tượng CModel.

Bất kỳ ý tưởng nào tại sao nó giống như thế này?

Cảm ơn.

+1

Tôi nghĩ mùa xuân tạo ra hạt đậu và proxy cho nó. Lớp proxy động mở rộng lớp cơ sở, vì vậy nó nên gọi super() trong hàm tạo của nó. Bạn có thể in dấu vết ngăn xếp trong constructor CModel để chắc chắn rằng (một cái gì đó giống như mới Exception(). PrintStackTrace()). – svaor

Trả lời

5

Mặc dù tôi không chắc chắn, tôi đoán là mùa xuân đầu tiên instantiates lớp thông thường, và sau đó làm cho một proxy CGLIB, mà là một phân lớp. Lưu ý rằng để khởi tạo, bạn nên sử dụng @PostConstruct, được đảm bảo sử dụng một lần.

Để xác minh giả thuyết của tôi, thêm một breakpoint trong các nhà xây dựng và xem khi nào nó được gọi - một trong những lần nó nên ngay sau khi CModel$EnhancedByCGLIB một cái gì đó

+1

Tôi nghĩ rằng bạn là chính xác. Tôi thực sự viết blog về nó [gần đây] (http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html), có lẽ OP sẽ tìm thấy một số chi tiết ở đó. BTW thậm chí còn có phương pháp đơn giản hơn để xác minh điều này: 'System.out.println (this)' - dòng in thứ hai sẽ mang lại một cái gì đó giống như 'CModel $ EnhancedByCGLIB'. –

+3

Tài liệu được mô tả trong [7.6 cơ chế ủy quyền] (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-proxying) – axtavt

3

Khi mùa xuân tạo ra một proxy để lớp học của bạn, nó sẽ sử dụng CGLIB để tạo một lớp phân lớp CModel. Ảnh hưởng ròng là constructor của bạn sẽ được gọi hai lần.

Kiểm tra các tài liệu Xuân cho biết thêm chi tiết (đặc biệt là viên đạn thứ ba): http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-proxying

Là một mặt lưu ý, mùa xuân sẽ sử dụng cơ chế proxy JDK nếu lớp học của bạn thực hiện một giao diện - và cơ chế proxy JDK sẽ không gọi hàm khởi tạo của bạn.

+1

Darn - trông giống như Tôi đã bị đánh vào cú đấm :) Xin lỗi vì câu trả lời trùng lặp. – wmkoch

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