Chào các em ,chủ để hôm nay chúng ta sẽ tìm hiểu về AOP Annotation có ý nghĩa là gì nhé .
1. Spring AOP Annotation là gì
Trong bài AOP advise chúng ta sử dụng xml để cấu hình cho advise, pointcut và around. Hôm nay chúng ta sẽ sử dụng annotation để làm AOP như @Before, @After, @AfterReturing, @AfterThrowing và @Around
2. Cấu hình file pom
Chúng ta thêm các thư viện AspectJrt và aspecttools vào trong dự án để sử dụng aop
Chúng ta thấy có annotation là @Loggable thì cái annotation này dùng ghi log và do chúng ta tự định nghĩa ra. Phần này anh sẽ nói rõ hơn trong phần 10 dưới đây.
3. Tạo Service
Chúng ta sẽ tạo Class EmployeeService để lấy Employee như sau
<beansxmlns="https://www.springframework.org/schema/beans"xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"xmlns:aop="https://www.springframework.org/schema/aop"xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-4.0.xsd
https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.0.xsd"><!-- Enable AspectJ style of Spring AOP --><aop:aspectj-autoproxy/><!-- Configure Employee Bean and initialize it --><beanname="employee"class="com.levunguyen.Employee"><propertyname="name"value="Le Vu Nguyen"></property></bean><!-- Configure EmployeeService bean --><beanname="employeeService"class="com.levunguyen.EmployeeService"><propertyname="employee"ref="employee"></property></bean><!-- Configure Aspect Beans, without this Aspects advices wont execute --><beanname="employeeAspect"class="com.levunguyen.EmployeeAspect"/><beanname="employeeAspectPointcut"class="com.levunguyen.EmployeeAspectPointcut"/><beanname="employeeAspectJoinPoint"class="com.levunguyen.EmployeeAspectJoinPoint"/><beanname="employeeAfterAspect"class="com.levunguyen.EmployeeAfterAspect"/><beanname="employeeAroundAspect"class="com.levunguyen.EmployeeAroundAspect"/><beanname="employeeAnnotationAspect"class="com.levunguyen.EmployeeAnnotationAspect"/></beans>
Đầu tiên chúng ta bật chức năng aop lên
1
<aop:aspectj-autoproxy/>
Tiếp đến chúng ta tạo các bean Employee
1
2
3
4
5
6
7
8
9
<!-- Configure Employee Bean and initialize it --><beanname="employee"class="com.levunguyen.Employee"><propertyname="name"value="Le Vu Nguyen"></property></bean><!-- Configure EmployeeService bean --><beanname="employeeService"class="com.levunguyen.EmployeeService"><propertyname="employee"ref="employee"></property></bean>
Ta có EmployeeAspect sử dụng annotation @Aspect trong đó ta định nghĩa phương thức nào cần hook trước khi chạy. Trong ví dụ này chúng ta áp dụng khi chạy phương thức getName
Một Aspect Class sẽ được đánh dấu bằng @Aspect
Annotation @Before được sử dụng để chạy trước khi method getName được gọi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;@AspectpublicclassEmployeeAspect{@Before("execution(public String getName())")publicvoidgetNameAdvice(){System.out.println("Executing Advice on getName()");}@Before("execution(*.com.levunguyen.*.get*())")publicvoidgetAllAdvice(){System.out.println("Service method getter called");}}
6. Ví dụ với AOP Pointcut Method
Chúng ta sử dụng phương thức nào sẽ được chạy AOP hoặc tất cả phương thức được chạy bằng sử dụng within
@AspectpublicclassEmployeeAspectPointcut{@Before("getNamePointcut()")publicvoidloggingAdvice(){System.out.println("Executing loggingAdvice on getName()");}@Before("getNamePointcut()")publicvoidsecondAdvice(){System.out.println("Executing secondAdvice on getName()");}@Pointcut("execution(public String getName())")publicvoidgetNamePointcut(){}@Before("allMethodsPointcut()")publicvoidallServiceMethodsAdvice(){System.out.println("Before executing service method");}//Pointcut to execute on all the methods of classes in a package@Pointcut("within(com.levunguyen.service.*)")publicvoidallMethodsPointcut(){}}
7. Ví dụ với AOP JoinPoint và Advice
Chúng ta sử dụng AOP cho các phương thức là set có trong Employee model
importorg.aspectj.lang.JoinPoint;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;@AspectpublicclassEmployeeAspectJoinPoint{@Before("execution(public void com.levunguyen.model..set*(*))")publicvoidloggingAdvice(JoinPointjoinPoint){System.out.println("Before running loggingAdvice on method="+joinPoint.toString());System.out.println("Arguments Passed="+Arrays.toString(joinPoint.getArgs()));}//Advice arguments, will be applied to bean methods with single String argument@Before("args(name)")publicvoidlogStringArguments(Stringname){System.out.println("String argument passed="+name);}}
EmployeeAfterAspect
8. Ví dụ với AOP After Aspect
Chúng ta sử dụng @After để chạy AOP khi method đã chạy xong
importorg.aspectj.lang.JoinPoint;importorg.aspectj.lang.annotation.After;importorg.aspectj.lang.annotation.AfterReturning;importorg.aspectj.lang.annotation.AfterThrowing;importorg.aspectj.lang.annotation.Aspect;@AspectpublicclassEmployeeAfterAspect{@After("args(name)")publicvoidlogStringArguments(Stringname){System.out.println("Running After Advice. String argument passed="+name);}@AfterThrowing("within(com.levunguyen.Employee)")publicvoidlogExceptions(JoinPointjoinPoint){System.out.println("Exception thrown in Employee Method="+joinPoint.toString());}@AfterReturning(pointcut="execution(* getName())",returning="returnString")publicvoidgetNameReturningAdvice(StringreturnString){System.out.println("getNameReturningAdvice executed. Returned String="+returnString);}}