Java 實(shí)現(xiàn)攔截器Interceptor的攔截功能方式
Java 里的攔截器是動(dòng)態(tài)攔截 action 調(diào)用的對(duì)象,它提供了一種機(jī)制可以使開(kāi)發(fā)者可以定義在一個(gè) action 執(zhí)行的前后執(zhí)行的代碼,也可以在一個(gè) action 執(zhí)行前阻止其執(zhí)行,同時(shí)也提供了一種可以提取 action 中可重用部分的方式。在 AOP(Aspect-Oriented Programming)中攔截器用于在某個(gè)方法或字段被訪問(wèn)之前進(jìn)行攔截,然后在之前或之后加入某些操作。
此外,攔截器在流行的開(kāi)源框架中也很常見(jiàn),其依賴的技術(shù)就是 Java 的動(dòng)態(tài)代理。理解攔截器的核心原理對(duì)理解這些開(kāi)源框架的體系結(jié)構(gòu)至關(guān)重要。下面,我們就以一個(gè)簡(jiǎn)單的模型的來(lái)說(shuō)明攔截器實(shí)現(xiàn)的一般方法。
模型主要分為五個(gè)模塊,分別:
- 業(yè)務(wù)組件,被代理和被攔截的對(duì)象;
- 代理處理器,實(shí)現(xiàn)了InvocationHandler接口的一個(gè)對(duì)象;
- 代理對(duì)象,Proxy對(duì)象;
- 攔截器,普通的 Java Bean,在調(diào)用業(yè)務(wù)方法之前或者之后會(huì)自動(dòng)攔截并執(zhí)行自己的一些方法;
- 客戶端,執(zhí)行業(yè)務(wù)處理的入口。
接下來(lái),我們就用 Java 語(yǔ)言來(lái)實(shí)現(xiàn)攔截器Interceptor的攔截功能:
第1步:創(chuàng)建業(yè)務(wù)組件接口 BusinessFacade
/**
* @author 維C果糖
* @create 2017-03-30
*
* GitHub:github.com/guobinhit
*
* 業(yè)務(wù)組件接口
*/
public interface BusinessFacade {
public void doSomething();
}
第2步:創(chuàng)建業(yè)務(wù)組件實(shí)現(xiàn)類 BusinessClass
/**
* @author 維C果糖
* @create 2017-03-30
*
* GitHub:github.com/guobinhit
*
* 業(yè)務(wù)組件接口的實(shí)現(xiàn)類
*/
public class BusinessClass implements BusinessFacade {
public void doSomething() {
System.out.println("在業(yè)務(wù)組件 BusinessClass 中調(diào)用方法: doSomething()");
}
}
第3步:創(chuàng)建攔截器 InterceptorClass
/**
* @author 維C果糖
* @create 2017-03-30
*
* GitHub:github.com/guobinhit
*
* 攔截器
*/
public class InterceptorClass {
// 在 action 之前調(diào)用
public void before(){
System.out.println("在攔截器 InterceptorClass 中調(diào)用方法: before()");
}
// 在 action 之后調(diào)用
public void after(){
System.out.println("在攔截器 InterceptorClass 中調(diào)用方法: after()");
}
}
第4步:創(chuàng)建動(dòng)態(tài)代理處理器工具 DynamicProxyHandler
/**
* @author 維C果糖
* @create 2017-03-30
*
* GitHub:github.com/guobinhit
*
* 動(dòng)態(tài)代理處理器工具
*/
public class DynamicProxyHandler implements InvocationHandler {
// 聲明被代理對(duì)象
private Object business;
// 創(chuàng)建攔截器
private InterceptorClass interceptor = new InterceptorClass();
/**
* 動(dòng)態(tài)生成一個(gè)代理類對(duì)象,并綁定被代理類和代理處理器。
*
* @param business
* @return 代理類對(duì)象
*/
public Object bind(Object business) {
this.business = business;
/**
* Proxy.newProxyInstance(參數(shù)1, 參數(shù)2, 參數(shù)3)
*
* 參數(shù)1, 表示被代理類的 ClassLoader
* 參數(shù)2, 表示被代理的接口
* 參數(shù)3, 表示代理處理器對(duì)象
*
* 該方法,返回代理實(shí)例
*/
return Proxy.newProxyInstance(business.getClass().getClassLoader(),
business.getClass().getInterfaces(),
this);
}
/**
* 代理需要調(diào)用的方法,并在該方法調(diào)用前后,先調(diào)用連接器的方法。
*
* @param proxy 代理類對(duì)象
* @param method 被代理的接口方法
* @param args 被代理接口方法的參數(shù)
* @return 方法調(diào)用返回的結(jié)果
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
interceptor.before();
result = method.invoke(business, args);
interceptor.after();
return null;
}
}
第5步:創(chuàng)建客戶端 ClientDemo
/**
* @author 維C果糖
* @create 2017-03-30
*
* GitHub:github.com/guobinhit
*
* 客戶端
*/
public class ClientDemo {
public static void main(String args[]) {
// 創(chuàng)建動(dòng)態(tài)代理處理工具
DynamicProxyHandler handler = new DynamicProxyHandler();
// 創(chuàng)建業(yè)務(wù)組件對(duì)象
BusinessFacade business = new BusinessClass();
// 創(chuàng)建業(yè)務(wù)組件對(duì)象,并用動(dòng)態(tài)代理綁定代理類
BusinessFacade businessProxy = (BusinessFacade) handler.bind(business);
// 調(diào)用業(yè)務(wù)組件中的方法,演示攔截器效果
businessProxy.doSomething();
}
}
運(yùn)行上面的項(xiàng)目代碼,結(jié)果如下圖所示:

如上圖所示,顯然我們攔截器的攔截功能實(shí)現(xiàn)啦!
通過(guò)這篇文章,我們可能會(huì)對(duì)攔截器的實(shí)現(xiàn)原理有一個(gè)更透徹的理解。
But,在真正的項(xiàng)目實(shí)踐之中,要想實(shí)現(xiàn)攔截器的功能,我們一般采用繼承類HandlerInterceptorAdapter或者抽象類AbstractInterceptor,或者實(shí)現(xiàn)HandleInterceptor接口。
也就是說(shuō),我們只需要關(guān)心如何重寫(xiě)方法,而不需要關(guān)心其內(nèi)部的實(shí)現(xiàn)原理。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java 全角半角字符轉(zhuǎn)換的方法實(shí)例
這篇文章主要介紹了java 全角半角字符轉(zhuǎn)換的方法,大家參考使用吧2013-11-11
Spring Cloud LoadBalancer 負(fù)載均衡詳解
本文介紹了如何在Spring Cloud中使用SpringCloudLoadBalancer實(shí)現(xiàn)客戶端負(fù)載均衡,并詳細(xì)講解了輪詢策略和隨機(jī)策略的配置方法,此外,還提供了部署到云服務(wù)器并在多個(gè)實(shí)例之間進(jìn)行負(fù)載均衡的步驟,感興趣的朋友一起看看吧2025-02-02
詳解Java的Hibernate框架中的set映射集與SortedSet映射
這篇文章主要介紹了詳解Java的Hibernate框架中的set映射集與SortedSet映射,Hibernate是Java的SSH三大web開(kāi)發(fā)框架之一,需要的朋友可以參考下2015-12-12
Java編程刪除鏈表中重復(fù)的節(jié)點(diǎn)問(wèn)題解決思路及源碼分享
這篇文章主要介紹了Java編程刪除鏈表中重復(fù)的節(jié)點(diǎn)問(wèn)題解決思路及源碼分享,具有一定參考價(jià)值,這里分享給大家,供需要的朋友了解。2017-10-10
springboot后端存儲(chǔ)富文本內(nèi)容的思路與步驟(含圖片內(nèi)容)
在所有的編輯器中,大概最受歡迎的就是富文本編輯器和MarkDown編輯器了,下面這篇文章主要給大家介紹了關(guān)于springboot后端存儲(chǔ)富文本內(nèi)容的思路與步驟的相關(guān)資料,需要的朋友可以參考下2023-04-04
IDEA下SpringBoot指定環(huán)境、配置文件啟動(dòng)操作過(guò)程
這篇文章主要介紹了IDEA下SpringBoot指定環(huán)境、配置文件啟動(dòng)過(guò)程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
web容器中實(shí)例化spring相關(guān)配置解析
這篇文章主要介紹了web容器中實(shí)例化spring相關(guān)配置解析,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
詳解JavaWeb過(guò)濾器 Filter問(wèn)題解決
過(guò)濾器就是對(duì)事物進(jìn)行過(guò)濾的,在Web中的過(guò)濾器,當(dāng)然就是對(duì)請(qǐng)求進(jìn)行過(guò)濾,我們使用過(guò)濾器,就可以對(duì)請(qǐng)求進(jìn)行攔截,然后做相應(yīng)的處理,實(shí)現(xiàn)許多特殊功能,今天主要給大家講解JavaWeb過(guò)濾器 Filter問(wèn)題解決,感興趣的朋友一起看看吧2022-10-10

