1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        一分鐘教你實(shí)現(xiàn)攔截器架構(gòu)

        共 3261字,需瀏覽 7分鐘

         ·

        2020-10-27 15:40



        攔截器主要用于攔截用戶請(qǐng)求并作相應(yīng)的處理.

        例如, Spring MVC通過攔截器可以進(jìn)行權(quán)限驗(yàn)證、記錄日志等;
        Mybatis通過插件實(shí)現(xiàn)分頁(yè)功能, 而這個(gè)插件就是攔截器.

        架構(gòu)圖如下:

        攔截器一般都是使用代理模式+責(zé)任鏈一起實(shí)現(xiàn)的, 下面一起看下這兩種設(shè)計(jì)模式.


        一. 代理模式


        代理模式給某一個(gè)對(duì)象提供一個(gè)代理對(duì)象, 并由代理對(duì)象控制對(duì)原對(duì)象的引用.

        代理模式是非常常見一個(gè)設(shè)計(jì)模式, 一般分為動(dòng)態(tài)代理和靜態(tài)代理, 我們以動(dòng)態(tài)代理為例看下, 如何實(shí)現(xiàn)一套代理模式.

        代理模式主要分為三部分: 接口, 實(shí)現(xiàn)類, 代理類.

        接口:

        public interface UserService { void addUser();}

        實(shí)現(xiàn)類:

        public class UserServiceImpl implements UserService {    public UserServiceImpl() {    }    public void addUser() {        System.out.println("this is addUser() method!");    }}

        代理類:

        public class UserServiceInvocationHandler implements InvocationHandler {    private Object targetObject;    public UserServiceInvocationHandler(Object targetObject) {        this.targetObject = targetObject;    }    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        System.out.println("do something");        Object result = method.invoke(targetObject, args);        return result;    }}

        測(cè)試類:

        private static void test1() { UserService targetObject = new UserServiceImpl(); UserServiceInvocationHandler proxy = new UserServiceInvocationHandler(targetObject); UserService object = (UserService) Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), proxy); object.addUser();}


        二.?責(zé)任鏈模式


        為方便多個(gè)代理的擴(kuò)展, 還需要引入過責(zé)任鏈模式.
        責(zé)任鏈模式是一種對(duì)象的行為模式. 在責(zé)任鏈模式里, 很多對(duì)象由包含下一個(gè)對(duì)象引用的對(duì)象而連接起來形成一條鏈. 請(qǐng)求在這個(gè)鏈上傳遞, 直到鏈上的某一個(gè)對(duì)象決定處理此請(qǐng)求.
        責(zé)任鏈設(shè)計(jì)模式能夠根據(jù)配置, 自由組合, 動(dòng)態(tài)調(diào)用.

        責(zé)任鏈模式實(shí)現(xiàn)代碼主分為三部分: 責(zé)任鏈, 鏈節(jié)點(diǎn), 處理實(shí)體.

        結(jié)合上面的代理模式, 實(shí)現(xiàn)代碼如下:

        責(zé)任鏈:

        public?class?InterceptorChain?{??private?final?List?interceptors?=?new?ArrayList();  public Object pluginAll(Object target) {    for (Interceptor interceptor : interceptors) {      target = interceptor.plugin(target);    }    return target;??}  public void addInterceptor(Interceptor interceptor) {    interceptors.add(interceptor);??}  public List getInterceptors() {    return Collections.unmodifiableList(interceptors);??}}

        鏈節(jié)點(diǎn):

        public?interface?Interceptor?{??Object?intercept(Invocation?invocation)?throws?Throwable;??Object?plugin(Object?target);}
        public?class?LogInterceptor?implements?Interceptor?{ @Override public Object intercept(Invocation invocation) throws Throwable { System.out.println(Thread.currentThread().getName()+ "\tlog intercept..."+ invocation.toString()); return invocation.proceed();????} @Override public Object plugin(Object target) { return Plugin.wrap(target, this); }}

        處理實(shí)體:

        public interface UserService { void addUser();}
        public?class?UserServiceImpl?implements?UserService?{????public?UserServiceImpl()?{} public void addUser() { System.out.println("this is addUser() method!");????}}

        測(cè)試類

        private static void test2() { InterceptorChain chain = new InterceptorChain(); chain.addInterceptor(new LogInterceptor()); UserService service = new UserServiceImpl(); UserService object = (UserService) chain.pluginAll(service); object.addUser();}

        為適應(yīng)更多應(yīng)用場(chǎng)景, ?可以在invoke()方法前后分別抽象出perHandler()和postHandler()方法, 進(jìn)行更多擴(kuò)展.

        注: 這里的類設(shè)計(jì)來源于mybatis的plugin模塊.



        總結(jié)

        萬(wàn)物之始, 大道至簡(jiǎn), 衍化至繁.

        通過代理和責(zé)任鏈兩個(gè)非常簡(jiǎn)單的模式, 就可以設(shè)計(jì)出高擴(kuò)展性, 低耦合的架構(gòu).

        END/往期推薦:




        1.微服務(wù)實(shí)戰(zhàn)系列

        2.springboot從入門到精通

        3.java入門到精通

        4.中間件等

        5.程序人生

        更多信息請(qǐng)關(guān)注公眾號(hào):「軟件老王」,關(guān)注不迷路,軟件老王和他的IT朋友們,分享一些他們的技術(shù)見解和生活故事。

        瀏覽 51
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            91久久精品无码一区二区毛片进 | 亚洲在线视频免费观看 | 黑人的巨大挺进娇妻最新章节 | 艹逼美女 | 日韩激情四射 | 激情无码又大又粗 | 日韩三级片在线 | 亚洲区在线播放 | 黄片视频在线免费看 | 欧美成人自拍 |