Hỏi đáp

Sử dụng AOP trong Spring Boot và AspectJ

AOP (Aspect Oriented Programming) chính là 1 kỹ thuật lập trình bổ sung cho lập trình hướng đối tượng (OOP), nó gây nên 1 cách suy nghĩ khác của lập trình cấu trúc. Đối tượng của OOP chính là class, còn đối tượng của AOP là aspect.

(p/s lý thuyết dài dòng và khó hiểu, đọc ví dụ và xem ứng dụng thực tế của nó giúp cho bạn dễ hình dung hơn nhiều)

Spring aop chính là gì

2.1 Insert Log vào các method

Bạn đang đọc: Sử dụng AOP trong Spring Boot và AspectJ

Chèn log khi chạy các service mà chưa sửa các method đó. Ví dụ mình có 1 method như thế này.

public String callDaoSuccess() return “dao1”;

Mình muốn chèn log khi method đó đã được gọi. Theo các logic thông thường thì cũng sẽ vào sửa method đó.

Phải sửa code trong methodNếu 1 Class có nhiều method mà muốn sửa thì phải sửa tất cả các method đó.

Tìm hiểu thêm: Rác thải là gì? Khái niệm và cách phân loại rác thải

public String callDaoSuccess() hoctuvangiamsat.com(“callDaoSuccess is called”); return “dao1”;

hoặc tìm tất cả những chỗ nào method được gọi, insert log vào trước => Tốn thời gian nếu method được dùng nhiều chỗ.

Để giải quyết vấn đề này AOP giúp cho chung ta thực hiện dễ hơn nhiều. Làm theo các bước như sau:

Thêm thư viện AOP

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version>2.4.5</version> </dependency>

Tạo 1 file khai báo Aspect

@Aspect @Configuration public class TestServiceAspect private Logger logger = hoctuvangiamsat.comogger(TestServiceAspect.class); @Before(“execution(* hoctuvangiamsat.com.*.*(..))”) public void before(JoinPoint joinPoint) hoctuvangiamsat.com(” before called ” + hoctuvangiamsat.comring());

Trả Trước Cho Người Bán Là Gì, cách Hạch Toán Phải Trả Cho Người Bán – Có Nghĩa Là Gì, Ý Nghĩa La Gi 2021

Có 1 khái niệm cần làm rõ ở đây:

@Aspect: Chỉ ra rằng class này chính là 1 Aspect (hiển nhiên)@Before: Chạy hàm này trước khi chạy hàm cần chèn(“execution(* hoctuvangiamsat.com..(..))”): Cái này giống như 1 regex để lực chọn method nó cũng sẽ áp dụng. Dấu * thứ số 1 chỉ rằng bất kỳ class nào trong package hoctuvangiamsat.com Dấu * thứ hai chi ra bất cứ method nào. Chúng ta có thể chỉ chính xác method

@Before(“execution(* hoctuvangiamsat.comDaoSuccess(..))”) public void before(JoinPoint joinPoint) hoctuvangiamsat.com(” before called ” + hoctuvangiamsat.comring());

Khi chạy ta sẽ thấy 2 log được sinh ra 1-> Log sinh ra tư Aspect, nó gọi trước khi gọi method 2-> Log sinh ra trong service

2021-05-11 17:42:41.460 INFO 36803 – [ main] hoctuvangiamsat.comServiceAspect : before called execution(String hoctuvangiamsat.comDaoSuccess()) 2021-05-11 17:42:41.474 INFO 36803 – [ main] hoctuvangiamsat.comDAO : callDaoSuccess is called

Để hiểu rõ hơn về bản chất, chúng ta đi vào các thuật ngữ:

2.2. Những thuật ngữ

Pointcut:

Điểm cắt, nó dùng để khai báo rằng Aspect đó sẽ đã được gọi khi nào. Ở ví dụ ở trên (“execution(* hoctuvangiamsat.com..(..))”) nó xảy ra ở tất cả các method trong class trong package hoctuvangiamsat.com.

Advice

Chúng ta sẽ làm gì khi xảy ra điểm cắt đó. Advice là logic mọi người muốn thực hiện. là đoạn code bên trong

public void before(JoinPoint joinPoint) hoctuvangiamsat.com(” before called ” + hoctuvangiamsat.comring());

Aspect

Đây là kết hợp giữa Pointcut , Advice, cái này không có nhiều điểm đặc biệt

Join Point

Khi code chạy và điều kiện pointcut đạt được. advice đã được chạy. Join Point chính là 1 instance của advice (cái này mình chưa dùng nhiều).

@Before, @After, @AfterReturning, @AfterThrowing

Đây là định nghĩa khi nào code của advice đã được chạy

@Before : chạy trược method@After: Chạy trong 2 trường hợp method chạy thành công hay có exception@AfterReturning: Chạy khi method chạy thành công@AfterThrowing: Chạy khi method có exception

@Around

Fantom (FTM) là gì? Tổng quan về nền tảng Fantom và FTM coin

Around cũng được sử dụng để chèn đầu và cuối của method, cách dùng nó hơi khác chút.

@Around(“execution(* hoctuvangiamsat.com.*.*(..))”) public void around(ProceedingJoinPoint joinPoint) throws Throwable Long startTime = hoctuvangiamsat.comentTimeMillis(); hoctuvangiamsat.com(“Start Time Taken by is ”, joinPoint, startTime); hoctuvangiamsat.comeed(); Long timeTaken = hoctuvangiamsat.comentTimeMillis() – startTime; hoctuvangiamsat.com(“Time Taken by is ”, joinPoint, timeTaken);

Method khi đã được gọi nó sẽ gọi vào around này trước, sau đó gọi đến

hoctuvangiamsat.comeed();

Để làm hàm, rồi tiếp tục gọi đến đoạn code tiếp theo.

Có 1 cách khác sử dụng Around chính là gây ra Annotation

@Around with Annotation

Tạo 1 annotation TrackTime

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TrackTime

Sửa @Around không phải execution nữa mà chính là annotation trỏ trực tiếp annotation của chúng ta.

@Around(“@annotation(com.ldt.demospringaop.aspect.TrackTime)”)

Method nào muốn track thì thêm annotation này vào @TrackTime

@TrackTime public String callMethodTrackTime() hoctuvangiamsat.com(“callDaoSuccess is called”); return “dao1”;

Xem chi tiết source code ở đây

Trong bài này giúp mọi người có cái nhìn tồng quan về Spring AOP. Hiểu đã được các khái niệm của nó, Làm 1 ví dụ cụ thể thấy được lợi ích mà nó đem lại.

Tham khảo cách nhận biết lan 5CT HO | hoctuvangiamsat.com

Tìm hiểu thêm: CVR là gì? các cách gia tăng CVR mà bất cứ marketer nào cũng phải biết