一個程式猿在夢中解決的 Bug 沒有人是不做夢的,在所有夢的排行中,白日夢最令人傷感。不知道身為程式猿的大家,有沒有睡了一覺,然後在夢中把睡之前代碼中怎麼也搞不定的 Bug 給解決的經歷?反正我是有過。 什麼是 AOP ? AOP 為 Aspect Oriented Programming 的縮寫, ...
一個程式猿在夢中解決的 Bug
沒有人是不做夢的,在所有夢的排行中,白日夢最令人傷感。不知道身為程式猿的大家,有沒有睡了一覺,然後在夢中把睡之前代碼中怎麼也搞不定的 Bug 給解決的經歷?反正我是有過。
什麼是 AOP ?
AOP 為 Aspect Oriented Programming 的縮寫,意為:面向切麵編程,通過預編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。AOP 是 OOP 的延續,是軟體開發中的一個熱點,也是 Spring 框架中的一個重要內容,是函數式編程的一種衍生範型。利用 AOP 可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
以上內容引用自百度百科
翻譯為人能聽懂的話來說就是: AOP 可以理解為在方法執行前後可以去完成相同的業務邏輯,而不需要你去改業務代碼。舉個例子吧:現在有一個需求,要在項目中的每一個方法前面都輸出一句:開始執行啦! 需求很明確了,常規的解決方式就是在每個具體的方法最前面加一句system.out.print("開始執行啦!");
,冒出這個想法的程式員是普通程式猿,當然,這是開個玩笑啦!這樣的代碼,如果一兩個方法用這樣的方式沒有任何問題完全可行,如果幾十個、幾百個這樣的方法呢?
這時候,我們就可以使用 AOP 來完成以上邏輯了,不需要改動任何一個方法,無侵入的方式來完成這個需求。
AOP 在實際項目中運用的場景主要有許可權管理(Authority Management)、事務管理(Transaction Management)、安全管理(Security)、日誌管理(Logging)和調試管理(Debugging)等。就是這些與業務邏輯不是很關聯密切的公共方法,我們就可以使用AOP。
Spring AOP 和 MVC 攔截器 又是什麼?
通過上面的解釋,我是知道了,AOP 其實就是可以算一種設計模式,或者說一種編程思想,而 Spring AOP 就是 Spring框架 對 AOP 這種思想進行了一系列技術實現和封裝,讓我們只需要配置一下就可以達到這個模式,在配置文件中使用<aop:config>
元素。那MVC 攔截器
又是什麼鬼呢?可以理解為是 Spring MVC 框架對 AOP 的一種實現方式,在配置文件中使用<mvc:interceptors>
元素進行配置。這兩種方式就是實現了 AOP 的編程思想,我們只需要進行一定的配置就可以了。現在好多人也都把 Spring AOP 和 MVC 攔截器看成是一種相同的方式,都叫攔截器或AOP。
開始擼一下代碼
1.新建一個TestInterceptor
類繼承於HandlerInterceptorAdapter
。
具體代碼:
package cn.mayongfa.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class TestInterceptor extends HandlerInterceptorAdapter {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 請求處理完成之後
System.out.println("請求處理完成啦!");
super.afterCompletion(request, response, handler, ex);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 處理器執行完畢之後
System.out.println("處理器執行完畢啦!");
super.postHandle(request, response, handler, modelAndView);
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 處理器實際執行之前
System.out.println("處理器執行之前!");
return super.preHandle(request, response, handler);
}
}
- preHandle(..):它在處理器實際執行 之前 會被執行;
- postHandle(..),它在處理器執行 完畢 以後被執行;
- afterCompletion(..),它在 整個請求處理完成 之後被執行。
這三個方法為各種類型的前處理和後處理需求提供了足夠的靈活性。
2.配置一下/WebContent/WEB-INF/springMVC-servlet.xml
中的<mvc:interceptors>
元素就可以攔截請求了。
<mvc:interceptors>
<!-- 直接定義在mvc:interceptors根下麵的Interceptor將攔截所有的請求 -->
<mvc:interceptor>
<!-- 定義在mvc:interceptor下麵的表示是對特定的請求才進行攔截的 -->
<mvc:mapping path="/api/**"/>
<bean class="cn.mayongfa.interceptor.TestInterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>
當然,你可以根據你的需求進行攔截,我這裡攔截的是api路徑下麵的所有請求。
3.測試一下
我的項目中有個 /api/user/getlist
請求,在瀏覽器輸入試一下。
請求數據成功,看一下控制台輸出:
看到我們在TestInterceptor
類中輸出已經列印出來,這就是Spring AOP 攔截器的基本實現。到這裡,你應該明白瞭如何使用 AOP 來進行一些與業務邏輯無關且必須在代碼前後執行的一些通用方法了,這就是我理解 AOP 的作用吧。具體代碼請訪問GitHub:
https://github.com/mafly/SpringDemo