Spring之AOP初步認識 【1】AOP概覽 什麼是AOP? (來自百度) 在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切麵編程,通過預編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,也是Sp ...
Spring之AOP初步認識
【1】AOP概覽
什麼是AOP?(來自百度)
在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切麵編程,通過預編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
然後我們舉一個比較簡單的慄子(來自:Spring 之 AOP)
我們一般做活動的時候,一般對每一個介面都會做活動的有效性校驗(是否開始、是否結束等等)、以及這個介面是不是需要用戶登錄。
按照正常的邏輯,我們可以這麼做。
這有個問題就是,有多少介面,就要多少次代碼copy。對於一個“懶人”,這是不可容忍的。好,提出一個公共方法,每個介面都來調用這個介面。這裡有點切麵的味道了。
同樣有個問題,我雖然不用每次都copy代碼了,但是,每個介面總得要調用這個方法吧。於是就有了切麵的概念,我將方法註入到介面調用的某個地方(切點)。
這樣介面只需要關心具體的業務,而不需要關註其他非該介面關註的邏輯或處理。
紅框處,就是面向切麵編程。
【2】AOP相關術語
概念定義
- Aspect(切麵): Aspect 聲明類似於 Java 中的類聲明,在 Aspect 中會包含著一些 Pointcut 以及相應的 Advice。
- Joint point(連接點):表示在程式中明確定義的點,典型的包括方法調用,對類成員的訪問以及異常處理程式塊的執行等等,它自身還可以嵌套其它 joint point。
- Pointcut(切點):表示一組 joint point,這些 joint point 或是通過邏輯關係組合起來,或是通過通配、正則表達式等方式集中起來,它定義了相應的 Advice 將要發生的地方。
- Advice(增強):Advice 定義了在 Pointcut 裡面定義的程式點具體要做的操作,它通過 before、after 和 around 來區別是在每個 joint point 之前、之後還是代替執行的代碼。
- Target(目標對象):織入 Advice 的目標對象.。
- Weaving(織入):將 Aspect 和其他對象連接起來, 並創建 Adviced object 的過程
Advice 的類型
- before advice(前置通知), 在 join point 前被執行的 advice.
- after return advice(後置通知), 在一個 join point 正常返回後執行的 advice
- after throwing advice(異常通知), 當一個 join point 拋出異常後執行的 advice
- after advice(返回通知), 無論一個 join point 是正常退出還是發生了異常, 都會被執行的 advice.
- around advice(環繞通知), 在 join point 前和 joint point 退出後都執行的 advice. 這個是最常用的 advice.
- introduction(引介),introduction可以為原有的對象增加新的屬性和方法。
【3】AOP示例
首先,創建一個OrderService,寫一個添加訂單的方法:
public class OrderService {
public void addOrder(){
System.err.println("添加訂單...");
}
}
我們要為這個方法運行前後添加通知方法,寫一個切麵類:
@Aspect
public class LogAspects {
@Pointcut("execution(* com.zl.springBase.aop.OrderService.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void logBegin() {
System.out.println("開始添加訂單了...");
}
@After("pointCut()")
public void logEnd() {
System.out.println("訂單添加結束...");
}
@AfterReturning("pointCut()")
public void logAfter() {
System.out.println("訂單添加正常結束...");
}
@AfterThrowing("pointCut()")
public void logException() {
System.out.println("訂單添加出現異常...");
}
}
然後將這兩個類添加到容器當中:
@Configuration
@EnableAspectJAutoProxy
public class MainConfig {
@Bean
public OrderService orderService(){
return new OrderService();
}
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
在測試類中運行添加訂單的方法:
@ContextConfiguration(classes = {MainConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class TestAspects {
@Autowired
private ApplicationContext applicationContext;
@Test
public void test(){
OrderService orderService = applicationContext.getBean(OrderService.class);
orderService.addOrder();
}
}
運行結果如下圖: