Chủ Nhật, 11 tháng 8, 2013

Spring AOP


Kinh nghiệm lập trình chỉ ra rằng, để hoàn thành một chương trình, bạn không chỉ phải giải quyết các business logic thỏa mãn được yêu cầu khách hàng mà con cần giải quyết những logic bắt buộc khác. Những logic này tuy không thể hiện các business rules, business processes của khách hàng nhưng lại luôn xuất hiện trong mọi chương trình. Vài ví dụ như: login/logout, validation, authentication và authorization, logging, trail log... Những thành phần vừa nêu giữ cho chương trình của bạn bền vững. Rắc rối ở chỗ nó xuất hiện ở nhiều nơi trong chương trình nên việc lập trình nó sẽ dẫn đến duplicate code nhiều nơi trong chương trình. Đây là một thiết kế xấu. Những code của các thành phần như vậy gọi là concern hoặc cross cutting code. Lập trình viên chúng ta luôn muốn viết code một lần mà chạy được nhiều nơi, độc lập để dễ tái sử dụng. Spring AOP sẽ giải quyết cho chúng ta các cross cutting code này. 

Mình sẽ trình bày một số khái niệm căn bản của spring AOP. Khi làm việc với Spring AOP bạn sẽ thấy các khái niệm này được sử dụng rất nhiều lần.


  • Join point: Đây là một method execution sẽ được cài aspect. Aspect sẽ được cài vào trước, sau hoặc xung quanh join point
  • Point cut: Đây là một expression cho phép Spring AOP match được aspect nào sẽ áp dụng cho join point nào.
  • Advice: là hành động thực hiện bởi aspect, chính là cross cutting code bạn muốn cài. Có ba loại advice chính: before advice, after advice và around advice. Around advice làm được tất cả mọi việc mà hai loại advice kể trên làm được nhưng theo nguyên lý thiết kế vừa đủ thì bạn chỉ nên dùng loại advice đáp ứng vừa đủ chính xác yêu cầu của bạn mà thôi.
  • Aspect: Hay còn gọi là advisor, là tập hợp của advice và point cut.
  • Target object: là object mà các method của nó sẽ được cài cắm các aspect. Target object không hề biết aspect được cài vào xung quanh nó. Kỳ diệu ở đây là nhờ đó bạn sẽ không phải chỉnh sửa target object.
  • AOP proxy: Là một object tạo bởi Spring AOP. Object này sẽ hình thành một lớp proxy chắn giữa method call và target object. Khái niệm proxy ở đây rất giống khái niệm proxy trong mạng máy tính. Vì nằm sau một proxy nên mọi target object còn được gọi là proxied object. Những advice sẽ được cài vào và gọi thực hiện trên proxy
  • Introduction: Đây là một new interface sẽ được khoác lên thêm cho target object. Spring AOP sẽ cung cấp implementation cho interface này. Tính năng này cho phép bạn bổ sung các interface mới cho target object mà bản thân object đấy lại không hề biết, nghĩa là bạn không cần chỉnh sửa code trong target object mà vẫn thêm tính năng cho nó.
  • Weaving: Là cách mà Spring AOP sẽ cài aspect vào join point. Những cross cutting code sẽ được chèn vào trước, sau hoặc xung quanh joint point. Cũng giống như các AOP framework khác, Spring AOP sẽ thực hiện weaving tại thời điểm runtime.

Để thực hiện các tính năng của mình, Spring AOP sẽ phải sử dụng aspectj nhưng là sử dụng không đầy đủ. Spring AOP support aspectj theo hai cách: @Aspectj hoặc schema-based. Kỹ thuật này chỉ đòi hỏi Spring AOP sử dụng aspectj để matching và compiling còn weaving thì Spring AOP có cơ chế riêng. Tất nhiên Spring AOP vẫn có cho phép sử dụng full-feature aspectj.

Có rất nhiều điểm spring AOP khác biệt với aspectj


  • Spring AOP sử dụng proxy để chặn method call và thực hiện advice trên đó còn aspectj thì có cơ chế khác hoàn toàn, không sử dụng đến proxy. Cũng vì dùng proxy mà Spring AOP không thể chặn được những self method call qua this vì những method call này xuất phát từ trong target object. Không có cản trở tương tự trên aspectj
  • Spring AOP không hỗ trợ đủ các designator của aspectj
  • Spring AOP hỗ trợ bean designator mà không có trong aspectj
  • Spring AOP có cơ chế weaving riêng không sử dụng cơ chế của aspectj

Bản chất của Spring AOP là proxy. Một proxy object sẽ bao lấy target object và chặn lời gọi đến method trong target object. Spring AOP có sử dụng hai loại proxy: JDK Dynamic proxy và CGLIB proxy. Loại CGLIB proxy nằm sẵn trong thư viện spring core, bạn không cần tìm kiếm thư viện cglib làm gì cả. Còn loại JDK Dynamic proxy thì nằm sẵn trong thư viện java core. Spring AOP sẽ chọn loại proxy được sử dụng tùy theo target object. Nếu target object implements interface thì JDK Dynamic proxy được dùng còn nếu ngược lại thì là CGLIB proxy. Spring AOP sẽ tự động tạo proxy lên các object được pointcut match khi bạn enable aspectj support. Tất nhiên Spring AOP cũng cho phép bạn tự định nghĩa proxy object sử dụng.

Không có nhận xét nào:

Đăng nhận xét