Spring AOP - Triển khai
Mùa xuân hỗ trợ @AspectJ annotation style cách tiếp cận và schema-based cách tiếp cận để thực hiện các khía cạnh tùy chỉnh.
Dựa trên lược đồ XML
Các khía cạnh được triển khai bằng cách sử dụng các lớp thông thường cùng với cấu hình dựa trên XML.
Để sử dụng các thẻ không gian tên AOP được mô tả trong phần này, bạn cần nhập lược đồ AOP mùa xuân, được mô tả như sau:
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop = "http://www.springframework.org/schema/aop"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<!-- bean definition & AOP specific configuration -->
</beans>
Tuyên bố một khía cạnh
An aspect được khai báo bằng cách sử dụng <aop:aspect> phần tử và hạt đệm được tham chiếu bằng cách sử dụng ref thuộc tính như sau.
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
Ở đây "aBean" sẽ được cấu hình và chèn phụ thuộc giống như bất kỳ Spring bean nào khác như bạn đã thấy trong các chương trước.
Khai báo một PointCut
A PointCutgiúp xác định các điểm tham gia (tức là các phương pháp) quan tâm sẽ được thực hiện với các lời khuyên khác nhau. Trong khi làm việc với cấu hình dựa trên Lược đồ XML, PointCut sẽ được định nghĩa như sau:
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:PointCut id = "businessService"
expression = "execution(* com.xyz.myapp.service.*.*(..))"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
Ví dụ sau định nghĩa một PointCut có tên 'businessService' sẽ khớp với việc thực thi phương thức getName () có sẵn trong lớp Sinh viên trong gói com.tutorialspoint.
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:PointCut id = "businessService"
expression = "execution(* com.tutorialspoint.Student.getName(..))"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
Khai báo Advices
Bạn có thể khai báo bất kỳ lời khuyên nào trong số năm lời khuyên bên trong <aop: domains> bằng cách sử dụng phần tử <aop: {ADVICE NAME}> như sau.
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:PointCut id = "businessService"
expression = "execution(* com.xyz.myapp.service.*.*(..))"/>
<!-- a before advice definition -->
<aop:before PointCut-ref = "businessService"
method = "doRequiredTask"/>
<!-- an after advice definition -->
<aop:after PointCut-ref = "businessService"
method = "doRequiredTask"/>
<!-- an after-returning advice definition -->
<!--The doRequiredTask method must have parameter named retVal -->
<aop:after-returning PointCut-ref = "businessService"
returning = "retVal"
method = "doRequiredTask"/>
<!-- an after-throwing advice definition -->
<!--The doRequiredTask method must have parameter named ex -->
<aop:after-throwing PointCut-ref = "businessService"
throwing = "ex"
method = "doRequiredTask"/>
<!-- an around advice definition -->
<aop:around PointCut-ref = "businessService"
method = "doRequiredTask"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
Bạn có thể sử dụng cùng một doRequiredTaskhoặc các phương pháp khác nhau cho những lời khuyên khác nhau. Các phương thức này sẽ được định nghĩa như một phần của mô-đun khía cạnh.
Dựa trên @AspectJ
@AspectJ đề cập đến một kiểu khai báo các khía cạnh như các lớp Java thông thường được chú thích bằng các chú thích Java 5. Hỗ trợ @AspectJ được kích hoạt bằng cách đưa phần tử sau vào trong tệp cấu hình dựa trên Lược đồ XML của bạn.
<aop:aspectj-autoproxy/>
Tuyên bố một khía cạnh
Các lớp Aspects giống như bất kỳ bean bình thường nào khác và có thể có các phương thức và trường giống như bất kỳ lớp nào khác, ngoại trừ việc chúng sẽ được chú thích bằng @Aspect như sau.
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AspectModule {
}
Chúng sẽ được cấu hình trong XML giống như bất kỳ bean nào khác như sau.
<bean id = "myAspect" class = "org.xyz.AspectModule">
<!-- configure properties of aspect here as normal -->
</bean>
Khai báo một PointCut
A PointCutgiúp xác định các điểm tham gia (tức là các phương pháp) quan tâm sẽ được thực hiện với các lời khuyên khác nhau. Trong khi làm việc với cấu hình dựa trên @AspectJ, khai báo PointCut có hai phần:
Một biểu thức PointCut xác định chính xác phương thức thực thi mà chúng ta quan tâm.
Chữ ký PointCut bao gồm tên và bất kỳ số lượng tham số nào. Phần thân thực tế của phương thức này không liên quan và trên thực tế phải trống.
Ví dụ sau định nghĩa một PointCut có tên 'businessService' sẽ khớp với việc thực thi mọi phương thức có sẵn trong các lớp thuộc gói com.xyz.myapp.service.
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* com.xyz.myapp.service.*.*(..))") // expression
private void businessService() {} // signature
Ví dụ sau định nghĩa một PointCut có tên 'getname' sẽ khớp với việc thực thi phương thức getName () có sẵn trong lớp Sinh viên dưới gói com.tutorialspoint.
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* com.tutorialspoint.Student.getName(..))")
private void getname() {}
Khai báo Advices
Bạn có thể khai báo bất kỳ lời khuyên nào trong số năm lời khuyên bằng cách sử dụng chú thích @ {ADVICE-NAME} như được cung cấp bên dưới. Điều này giả định rằng bạn đã xác định phương thức chữ ký PointCut businessService ().
@Before("businessService()")
public void doBeforeTask(){
...
}
@After("businessService()")
public void doAfterTask(){
...
}
@AfterReturning(PointCut = "businessService()", returning = "retVal")
public void doAfterReturnningTask(Object retVal){
// you can intercept retVal here.
...
}
@AfterThrowing(PointCut = "businessService()", throwing = "ex")
public void doAfterThrowingTask(Exception ex){
// you can intercept thrown exception here.
...
}
@Around("businessService()")
public void doAroundTask(){
...
}
Bạn có thể xác định nội tuyến PointCut cho bất kỳ lời khuyên nào. Sau đây là một ví dụ để xác định PointCut nội tuyến cho lời khuyên trước.
@Before("execution(* com.xyz.myapp.service.*.*(..))")
public doBeforeTask(){
...
}