詳解Spring AOP 攔截器的基本實(shí)現(xiàn)
一個(gè)程序猿在夢(mèng)中解決的 Bug
沒有人是不做夢(mèng)的,在所有夢(mèng)的排行中,白日夢(mèng)最令人傷感。不知道身為程序猿的大家,有沒有睡了一覺,然后在夢(mèng)中把睡之前代碼中怎么也搞不定的 Bug 給解決的經(jīng)歷?反正我是有過。
什么是 AOP ?
AOP 為 Aspect Oriented Programming 的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP 是 OOP 的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是 Spring 框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用 AOP 可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。
翻譯為人能聽懂的話來說就是: AOP 可以理解為在方法執(zhí)行前后可以去完成相同的業(yè)務(wù)邏輯,而不需要你去改業(yè)務(wù)代碼。舉個(gè)例子吧:現(xiàn)在有一個(gè)需求,要在項(xiàng)目中的每一個(gè)方法前面都輸出一句:開始執(zhí)行啦! 需求很明確了,常規(guī)的解決方式就是在每個(gè)具體的方法最前面加一句system.out.print("開始執(zhí)行啦!");,冒出這個(gè)想法的程序員是普通程序猿,當(dāng)然,這是開個(gè)玩笑啦!這樣的代碼,如果一兩個(gè)方法用這樣的方式?jīng)]有任何問題完全可行,如果幾十個(gè)、幾百個(gè)這樣的方法呢?
這時(shí)候,我們就可以使用 AOP 來完成以上邏輯了,不需要改動(dòng)任何一個(gè)方法,無侵入的方式來完成這個(gè)需求。
AOP 在實(shí)際項(xiàng)目中運(yùn)用的場(chǎng)景主要有權(quán)限管理(Authority Management)、事務(wù)管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和調(diào)試管理(Debugging)等。就是這些與業(yè)務(wù)邏輯不是很關(guān)聯(lián)密切的公共方法,我們就可以使用AOP。
Spring AOP 和 MVC 攔截器 又是什么?
通過上面的解釋,我是知道了,AOP 其實(shí)就是可以算一種設(shè)計(jì)模式,或者說一種編程思想,而 Spring AOP 就是 Spring框架 對(duì) AOP 這種思想進(jìn)行了一系列技術(shù)實(shí)現(xiàn)和封裝,讓我們只需要配置一下就可以達(dá)到這個(gè)模式,在配置文件中使用<aop:config>元素。那MVC 攔截器又是什么鬼呢?可以理解為是 Spring MVC 框架對(duì) AOP 的一種實(shí)現(xiàn)方式,在配置文件中使用<mvc:interceptors>元素進(jìn)行配置。這兩種方式就是實(shí)現(xiàn)了 AOP 的編程思想,我們只需要進(jìn)行一定的配置就可以了?,F(xiàn)在好多人也都把 Spring AOP 和 MVC 攔截器看成是一種相同的方式,都叫攔截器或AOP。
開始擼一下代碼
1.新建一個(gè)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 {
// 請(qǐng)求處理完成之后
System.out.println("請(qǐng)求處理完成啦!");
super.afterCompletion(request, response, handler, ex);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 處理器執(zhí)行完畢之后
System.out.println("處理器執(zhí)行完畢啦!");
super.postHandle(request, response, handler, modelAndView);
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 處理器實(shí)際執(zhí)行之前
System.out.println("處理器執(zhí)行之前!");
return super.preHandle(request, response, handler);
}
}
- preHandle(..):它在處理器實(shí)際執(zhí)行 之前 會(huì)被執(zhí)行;
- postHandle(..),它在處理器執(zhí)行 完畢 以后被執(zhí)行;
- afterCompletion(..),它在 整個(gè)請(qǐng)求處理完成 之后被執(zhí)行。
這三個(gè)方法為各種類型的前處理和后處理需求提供了足夠的靈活性。
2.配置一下/WebContent/WEB-INF/springMVC-servlet.xml中的<mvc:interceptors>元素就可以攔截請(qǐng)求了。
<mvc:interceptors>
<!-- 直接定義在mvc:interceptors根下面的Interceptor將攔截所有的請(qǐng)求 -->
<mvc:interceptor>
<!-- 定義在mvc:interceptor下面的表示是對(duì)特定的請(qǐng)求才進(jìn)行攔截的 -->
<mvc:mapping path="/api/**"/>
<bean class="cn.mayongfa.interceptor.TestInterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>
當(dāng)然,你可以根據(jù)你的需求進(jìn)行攔截,我這里攔截的是api路徑下面的所有請(qǐng)求。
3.測(cè)試一下
我的項(xiàng)目中有個(gè) /api/user/getlist 請(qǐng)求,在瀏覽器輸入試一下。

請(qǐng)求數(shù)據(jù)成功,看一下控制臺(tái)輸出:

看到我們?cè)?code>TestInterceptor類中輸出已經(jīng)打印出來,這就是Spring AOP 攔截器的基本實(shí)現(xiàn)。到這里,你應(yīng)該明白了如何使用 AOP 來進(jìn)行一些與業(yè)務(wù)邏輯無關(guān)且必須在代碼前后執(zhí)行的一些通用方法了,這就是我理解 AOP 的作用吧。
下載地址:SpringDemo_jb51.rar
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
IDEA報(bào)錯(cuò):java?找不到符號(hào)圖文解決過程
這篇文章主要給大家介紹了關(guān)于IDEA報(bào)錯(cuò):java?找不到符號(hào)解決的相關(guān)資料,運(yùn)行項(xiàng)目時(shí)Idea報(bào)錯(cuò),提示找不到符號(hào),但是這個(gè)類在項(xiàng)目里是存在的,網(wǎng)上找了很多文章都沒解決,浪費(fèi)了一個(gè)下午終于弄好了,記錄一下,需要的朋友可以參考下2023-08-08
Java實(shí)現(xiàn)一鍵獲取Mysql所有表字段設(shè)計(jì)和建表語句的工具類
這篇文章主要為大家詳細(xì)介紹了如何利用Java編寫一個(gè)工具類,可以實(shí)現(xiàn)一鍵獲取Mysql所有表字段設(shè)計(jì)和建表語句,感興趣的小伙伴可以了解一下2023-05-05
elasticsearch kibana簡(jiǎn)單查詢講解
今天小編就為大家分享一篇關(guān)于elasticsearch kibana簡(jiǎn)單查詢講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-02-02
Java中的String.valueOf()和toString()方法區(qū)別小結(jié)
字符串操作是開發(fā)者日常編程任務(wù)中不可或缺的一部分,轉(zhuǎn)換為字符串是一種常見需求,其中最常見的就是String.valueOf()和toString()方法,本文主要介紹了Java中的String.valueOf()和toString()方法區(qū)別小結(jié),感興趣的可以了解一下2025-04-04
springboot druid數(shù)據(jù)庫(kù)配置密碼加密的實(shí)現(xiàn)
Druid是阿里開發(fā)的數(shù)據(jù)庫(kù)連接池,本文主要介紹了springboot druid數(shù)據(jù)庫(kù)配置密碼加密的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06
Java線程池流程編排運(yùn)用實(shí)戰(zhàn)源碼
這篇文章主要介紹了Java線程池流程編排運(yùn)用實(shí)戰(zhàn)源碼,就在流程引擎的基礎(chǔ)上運(yùn)用?ThreadPoolExecutor,使用線程池實(shí)現(xiàn)?SpringBean?的異步執(zhí)行2022-03-03
簡(jiǎn)單講解Java的Socket網(wǎng)絡(luò)編程的多播與廣播實(shí)現(xiàn)
這篇文章主要介紹了Java的Socket網(wǎng)絡(luò)編程的多播與廣播實(shí)現(xiàn),包括網(wǎng)絡(luò)編程發(fā)送和接受數(shù)據(jù)的一些基礎(chǔ)知識(shí)整理,需要的朋友可以參考下2016-01-01
SpringBoot快速過濾出一次請(qǐng)求的所有日志的示例代碼
在現(xiàn)網(wǎng)出現(xiàn)故障時(shí),我們經(jīng)常需要獲取一次請(qǐng)求流程里的所有日志進(jìn)行定位,本文給大家介紹了SpringBoot如何快速過濾出一次請(qǐng)求的所有日志,文中有相關(guān)的代碼和示例供大家參考,需要的朋友可以參考下2024-03-03

