用 Java 实现拦截器 Interceptor 的拦截功能
Java 里的攔截器是動態攔截 action 調用的對象,它提供了一種機制可以使開發者可以定義在一個 action 執行的前后執行的代碼,也可以在一個 action 執行前阻止其執行,同時也提供了一種可以提取 action 中可重用部分的方式。在 AOP(Aspect-Oriented Programming)中攔截器用于在某個方法或字段被訪問之前進行攔截,然后在之前或之后加入某些操作。
此外,攔截器在流行的開源框架中也很常見,其依賴的技術就是 Java 的動態代理。理解攔截器的核心原理對理解這些開源框架的體系結構至關重要。下面,我們就以一個簡單的模型的來說明攔截器實現的一般方法。模型主要分為五個模塊,分別:
- 業務組件,被代理和被攔截的對象;
- 代理處理器,實現了InvocationHandler接口的一個對象;
- 代理對象,Proxy對象;
- 攔截器,普通的 Java Bean,在調用業務方法之前或者之后會自動攔截并執行自己的一些方法;
- 客戶端,執行業務處理的入口。
接下來,我們就用 Java 語言來實現攔截器Interceptor的攔截功能:
第 1 步:創建業務組件接口 BusinessFacade
/*** @author 維C果糖* @create 2017-03-30** GitHub:github.com/guobinhit** 業務組件接口*/ public interface BusinessFacade {public void doSomething(); }第 2步:創建業務組件實現類 BusinessClass
/*** @author 維C果糖* @create 2017-03-30** GitHub:github.com/guobinhit** 業務組件接口的實現類*/ public class BusinessClass implements BusinessFacade {public void doSomething() {System.out.println("在業務組件 BusinessClass 中調用方法: doSomething()");} }第 3 步:創建攔截器 InterceptorClass
/*** @author 維C果糖* @create 2017-03-30** GitHub:github.com/guobinhit** 攔截器*/ public class InterceptorClass {// 在 action 之前調用public void before(){System.out.println("在攔截器 InterceptorClass 中調用方法: before()");}// 在 action 之后調用public void after(){System.out.println("在攔截器 InterceptorClass 中調用方法: after()");} }第 4 步:創建動態代理處理器工具 DynamicProxyHandler
/*** @author 維C果糖* @create 2017-03-30** GitHub:github.com/guobinhit** 動態代理處理器工具*/ public class DynamicProxyHandler implements InvocationHandler {// 聲明被代理對象private Object business;// 創建攔截器private InterceptorClass interceptor = new InterceptorClass();/*** 動態生成一個代理類對象,并綁定被代理類和代理處理器。** @param business* @return 代理類對象*/public Object bind(Object business) {this.business = business;/*** Proxy.newProxyInstance(參數1, 參數2, 參數3)** 參數1, 表示被代理類的 ClassLoader* 參數2, 表示被代理的接口* 參數3, 表示代理處理器對象** 該方法,返回代理實例*/return Proxy.newProxyInstance(business.getClass().getClassLoader(),business.getClass().getInterfaces(),this);}/*** 代理需要調用的方法,并在該方法調用前后,先調用連接器的方法。** @param proxy 代理類對象* @param method 被代理的接口方法* @param args 被代理接口方法的參數* @return 方法調用返回的結果* @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 步:創建客戶端 ClientDemo
/*** @author 維C果糖* @create 2017-03-30** GitHub:github.com/guobinhit** 客戶端*/ public class ClientDemo {public static void main(String args[]) {// 創建動態代理處理工具DynamicProxyHandler handler = new DynamicProxyHandler();// 創建業務組件對象BusinessFacade business = new BusinessClass();// 創建業務組件對象,并用動態代理綁定代理類BusinessFacade businessProxy = (BusinessFacade) handler.bind(business);// 調用業務組件中的方法,演示攔截器效果businessProxy.doSomething();} }運行上面的項目代碼,結果如下圖所示:
如上圖所示,顯然我們攔截器的攔截功能實現啦!
通過這篇文章,我們可能會對攔截器的實現原理有一個更透徹的理解。But,在真正的項目實踐之中,要想實現攔截器的功能,我們一般采用繼承類HandlerInterceptorAdapter或者抽象類AbstractInterceptor,或者實現HandleInterceptor接口。也就是說,我們只需要關心如何重寫方法,而不需要關心其內部的實現原理。
總結
以上是生活随笔為你收集整理的用 Java 实现拦截器 Interceptor 的拦截功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 俞敏洪励志语录
- 下一篇: Jmeter 添加kafka支持