Ở bài viết trước chúng ta đã cùng nhau tìm hiểu về các khái niệm có trong AOP, thì biết nôm na Aspect Oriented Programming (AOP) là một trong những tính năng cực kì hữu ích và quan trọng của Spring framework. Nó chia toàn bộ code thành các thành phần nhỏ.
Về cơ bản, ứng dụng Spring Boot thường được chia thành 3 tầng cơ bản:
- Tầng Web Layer, dùng để expose các Restful endpoint
- Tầng Business layer dùng để xử lý các logic nghiệp vụ
- Tầng Data layer cho việc truy xuất data từ datasource
Biết rằng mỗi tầng sẽ có các nhiệm vụ, chức năng riêng nhưng chúng vẫn sẽ có những khía cạnh (Aspect) chung như là ghi log, validate,... Những khịa cạnh này trong AOP được gọi là cross-cutting concerns.
Đoạn code dưới đây thêm thư viện hỗ trợ AOP cho ứng dụng
AOP cũng giống như OOP ở chỗ nó chia code ra thành những phần nhỏ hơn dễ dàng trong việc tái sử dụng, quản lý và phát triển code sau này.
Ngoài ra AOP cũng cung cấp khả năng thêm module vào chương trình tại thời điểm chạy.
Cross-cutting concerns là các phần của một chương trình phụ thuộc hoặc phải ảnh hưởng đến nhiều phần khác của hệ thống. Điều này tương tự như việc động tác chèn một module hoàn chỉnh (ghi nhật ký, bộ nhớ cache, v.v.) vào Spring framework một cách động.
Ví dụ như ta có logging, caching hay monitoring là những ví dụ điển hình cho cross-cutting concerns trong AOP. Trong bất kì lúc nào, bất chấp nơi đâu thì các module này có thể thêm vào hệ thống một cách dễ dàng.
Về cơ chế thì Spring AOP có thể can thiệp các method của ứng dụng. Điều này nhằm thực hiện một số hành động bổ sung trong quá trình khởi tạo thuộc tính, khởi tạo phương thức hoặc hủy bỏ.
Khái niệm cần nắm
Nhắc lại ngắn gọn về các khái niệm đã để cập ở bài trước, chúng ta có:
Aspect: Aspect là một vấn đề cần được thực hiện trong Spring framework hoặc ứng dụng. Một ứng dụng có thể có nhiều aspect như ghi nhật ký (logging), bảo mật (security), giám sát (monitoring).
Join Point: Điểm nối (Join Point) là một điểm trong mã chương trình mà một vấn đề hay aspect có thể được chèn vào (plugin).
Advice: Advice là việc thực hiện thực tế của một aspect. Advice đề xuất tại thời điểm nào chúng ta cần thực thi mã, có thể là trước hoặc sau khi phương thức được thực thi.
Advice có thể được thực thi tại các điểm thời gian sau:
- Before (Trước): Advice được thực thi trước khi phương thức được gọi.
- After returning (Sau khi trả về): Advice được thực thi sau khi phương thức đã trả về kết quả.
- After throwing (Sau khi ném ngoại lệ): Advice được thực thi sau khi một ngoại lệ được ném từ phương thức.
- After (Sau): Advice được thực thi sau khi phương thức hoàn thành, bao gồm cả khi có ngoại lệ xảy ra.
- Around (Xung quanh): Advice được thực thi xung quanh phương thức, cho phép kiểm soát toàn bộ quá trình thực thi bên trong phương thức.
Mỗi loại advice đều có mục đích và cách thực thi riêng, cho phép can thiệp và thực hiện các hành động bổ sung tại các điểm thời gian khác nhau trong quá trình thực thi của phương thức.
Pointcut: Pointcut (Điểm cắt) là những điểm nối trong mã chương trình mà advice (lời khuyên) nên được thực thi. Một aspect đơn có thể có nhiều pointcut để xác định nơi nó cần được thực thi.
Introduction: Introduction (Giới thiệu) cho phép bạn thêm các phương thức hoặc thuộc tính mới vào các lớp hiện có.
Target object: Đây là đối tượng trong ứng dụng mà advice sẽ được áp dụng.
Weaving: Weaving (Kết nối) là một kỹ thuật để tạo kết nối giữa các aspect tại thời điểm tải, biên dịch hoặc thời gian chạy của chương trình.
Tiếp theo hãy bắt tay tạo thử 1 project Spring Boot để hiểu về cách hoạt động của AOP nào !
Thực hành
- Hãy tạo một dự án bằng cách sử dụng Spring Initializr theo liên kết.
- Điền thông tin Group và Artifact như com.javadoubts và practice tương ứng.
- Thêm các phụ thuộc (dependencies) như Spring Web và Spring Boot Actuator như đã được đề cập trong ảnh chụp màn hình dưới đây.
- Thêm các thông tin như được đề cập trong ảnh chụp màn hình dưới đây. Thêm các phụ thuộc (dependencies) như Spring Web và Spring Boot Actuator.
Hãy giải nén tệp tin đã được tải về và nhập vào Spring Tool Suite. Thêm các phụ thuộc dưới đây vào tệp pom.xml như một phần của dự án
Tạo lớp UserController.java như hình bên dưới:
@RestController được sử dụng để tạo các dịch vụ web RESTful có thể được truy cập bằng các phương thức HTTP như GET, POST, v.v. Nó kết hợp các chú thích @Controller và @ResponseBody.
@GetMapping được sử dụng để ánh xạ yêu cầu HTTP GET. Điều này chủ yếu được sử dụng để lấy/dùng dữ liệu từ máy chủ.
Tạo một lớp UserServiceAspect.java khác. Khai báo chú thích @Aspect và @Component ở đầu lớp.
value="execution(* com.javadoubts.practice..*(..))" Cú pháp trên đảm bảo rằng advice sẽ được gọi cho mọi phương thức lớp bên trong gói com.javadoubts.practice.
@Aspect: Chú thích @Aspect được sử dụng để khai báo lớp này là một Aspect.
@Before: Advice với chú thích @Before sẽ được gọi trước mỗi lần thực thi hàm.
@After: Advice với chú thích @After sẽ được gọi sau mỗi lần thực thi hàm.
@AfterReturning: Advice với chú thích @AfterReturning sẽ được thực thi ngay sau khi hàm trả về giá trị.
@Around: Advice với chú thích @Around sẽ được thực thi trước và sau điểm nối (join point).
joinPoint.proceed(): Gọi phương thức joinPoint.proceed() là quan trọng để gọi advice tiếp theo trong chuỗi.
Để sử dụng AOP trong ứng dụng Spring Boot, cần khai báo chú thích được đánh dấu bên dưới trên đỉnh của lớp main như được hiển thị dưới đây:
Nhấp chuột phải vào tệp PracticeApplication.java và chọn "Run as" hoặc "Chạy như" sau đó chọn "Spring Boot App" để chạy ứng dụng Spring Boot.
Truy cập vào http://localhost:8080/users sẽ thấy
Cảm ơn các bạn đã dành thời gian, hẹn gặp các bạn ở các bài viết sau 👋