【原】通過BeanNameAutoProxyCreator改變臃腫代碼

来源:http://www.cnblogs.com/zdd-java/archive/2017/11/19/7861824.html
-Advertisement-
Play Games

前言: 最近接手了一個項目,大概過了下需求,然後打開項目準備開搞的時候發現一個問題,這個項目是提供rest服務的一個web項目,其中很多關鍵的查詢都調用這個項目,之前的開發人員為了監控每個方法的執行時間,在方法開始和結束寫了很多logger.info("耗時:"+time)這種代碼。很顯然這是不合理 ...


  前言:

              最近接手了一個項目,大概過了下需求,然後打開項目準備開搞的時候發現一個問題,這個項目是提供rest服務的一個web項目,其中很多關鍵的查詢都調用這個項目,之前的開發人員為了監控每個方法的執行時間,在方法開始和結束寫了很多logger.info("耗時:"+time)這種代碼。很顯然這是不合理的,因為在項目里到處有這樣的代碼存在,沒有做到面向對象,而JAVA最基本的就是面向對象,並且對於有1-2年的開發人員來說不僅僅要考慮如何完功能,還要考慮如何把代碼優化好。廢話不多說,簡單描述下我的改造過程。

  

  •    創建一個方法攔截器:

/**
 * 用來監控方法的執行時間-- 對應配置文件是spring-servlet.xml
 * PS:必須放到springmvc的配置文件里,放在spring父容器裡面由於先初始化的是spring父容器上下文,先實例化的是除@Controller外的bean,所以無法生成代理。
 *
 * @author dada
 * @version $Id: MethodTimeAdvice.java, v 0.1
 * @date 2017年11月15日 09:47:23
 */
public class MethodTimeAdvice implements MethodInterceptor {

    private final static Logger logger = Logger.getLogger("DAL-MONITOR");

    /**
     * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
     */
    public Object invoke(MethodInvocation invocation) throws Throwable {
        //用 commons-lang 提供的 StopWatch 計時,Spring 也提供了一個 StopWatch
        StopWatch clock = new StopWatch();
        clock.start(); //計時開始
        Object result = null;
        //監控的方法名
        String methodName = getRequestMappingName(invocation);
        if(null == methodName){
            methodName = invocation.getMethod().getDeclaringClass().getSimpleName();
        }
        try {
            //這個是我們監控的bean的執行並返回結果
            result = invocation.proceed();
        } catch (Throwable e) {
            //監控的類名
            String className = invocation.getMethod().getDeclaringClass().getSimpleName();
            //監控的參數
            Object[] objs = invocation.getArguments();
            logger.error("控制層執行異常,方法名:" + className + "參數: " + getString(objs), e);
            throw e;
        }
        clock.stop(); //計時結束
        if (logger.isInfoEnabled()) {
            logger.info("[  " + methodName + "  ] 執行時間:" + clock.getTime() + " ms ");
        }
        return result;
    }

    /**
     * 這個類主要是用於輸出方法的參數
     *
     * @param objs
     * @return
     */
    @SuppressWarnings("unchecked")
    public String getString(Object[] objs) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0, len = objs.length; i < len; i++) {
            if (objs[i] instanceof String) {
                stringBuffer.append("String類型:" + objs[i].toString());
            } else if (objs[i] instanceof Map) {
                HashMap<String, Object> hashMap = (HashMap<String, Object>) objs[i];
                HashMap<String, Object> map = hashMap;
                HashSet<String> set = (HashSet<String>) map.keySet();
                stringBuffer.append("Map類型");
                for (String str : set) {
                    stringBuffer.append(str + "=" + map.get(str));
                }
            } else if (objs[i] instanceof Integer) {
                stringBuffer.append("整數類型:");
                stringBuffer.append(objs[i].toString());
            } else {
                stringBuffer.append(objs[i].toString());
            }
        }
        return stringBuffer.toString();
    }


    public String getRequestMappingName(MethodInvocation invocation){
        Method method = invocation.getMethod();
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if(requestMapping!=null){
            return requestMapping.name();
        }
        return null;
    }
}

 

 

  •   配置spring BeanNameAutoProxyCreator 用來攔截上面的 MethodTimeAdvice

<bean id="methodTimeAdvice" class="com.i2p.admin.interceptor.MethodTimeAdvice" />

    <!-- 根據 Bean 的名字自動實現代理攔截 -->
    <bean
            class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="interceptorNames">
            <list>
                <value>methodTimeAdvice</value>
            </list>
        </property>
        <property name="beanNames">
            <list>
                <!-- 添加到其中的 Bean 自動就被代理攔截了(下麵的是對應的bean的名稱,那麼當請求InnovatePartBorrowController任何一個方法都會執行MethodTimeAdvice裡面的Invoke方法) -->
                <value>innovatePartBorrowController</value>
            </list>
        </property>
    </bean>

 

   

總結:

   通過spring 代理,不僅減少了代碼的copy工作,同時又方便管理;至於後續功能的擴展,我們只需要在spring-mvc.xml里動態配置好對應的bean就能實現日誌的列印。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 本篇將結合JDK1.6的TreeMap源碼,來一起探索紅-黑樹的奧秘。紅黑樹是解決二叉搜索樹的非平衡問題。 當插入(或者刪除)一個新節點時,為了使樹保持平衡,必須遵循一定的規則,這個規則就是紅-黑規則: 1) 每個節點不是紅色的就是黑色的 2) 根總是黑色的 3) 如果節點是紅色的,則它的子節 ...
  • 本文主要給大家分享使用matlab編寫代碼,完成課程設計、畢業設計或者研究項目時,matlab調試程式的技巧和方法。 快速完成一個項目,最簡單的方法就是利用前人的開源代碼,然後根據自己項目的具體需求和參數,對已有代碼進行調試,並增加或刪減部分功能,最終實現自己項目的全部功能。所謂“站在前人的肩膀上... ...
  • Joinpoint 連接點 Pointcut 切入點 Advice 通知/增強 舉例: Aspact 切麵 比如給add()增加日誌功能的過程即稱為切麵 還有幾個術語知道就可以,不常用 Introduction (引入)使用動態的方法在原有屬性基礎上 添加新屬性的操作 ...
  • 前言: 之前寫Java服務端處理POST請求時遇到了請求體轉換成字元流所用編碼來源的疑惑,在doPost方法里通過request.getReader()獲取的BufferedReader對象內部的 Reader用的是什麼編碼將位元組流轉換成字元流的呢?又是在哪裡設置呢和什麼時候生效的呢?通過查找資料, ...
  • 作者:NiceCui 本文謝絕轉載,如需轉載需徵得作者本人同意,謝謝。 本文鏈接:http://www.cnblogs.com/NiceCui/p/7862377.html 郵箱:[email protected] 日期:2017-11-19 Python學習二:詞典基礎詳解 (學習不要求多,小計劃 ...
  • 流程式控制制 與C語言不通的是python的流程式控制制代碼塊不是用{}花括弧表示的,而是強制縮進來控制的;而且縮進必須一致,官方推薦是使用4個空格,不建議使用tab(製表符)做縮進,一是不同的系統tab所占寬度不一致,會比較亂,二是由於python要求同級縮進必須保持一致,所以有些時候看上去是對齊l,但是 ...
  • Composer是一個非常流行的PHP包依賴管理工具,已經取代PEAR包管理器,對於PHP開發者來說掌握Composer是必須的. 對於使用者來說Composer非常的簡單,通過簡單的一條命令將需要的代碼包下載到vendor目錄下,然後開發者就可以引入包並使用了.其中的關鍵在於你項目定義的compo ...
  • 類的繼承 上面代碼中yello_person繼承了person父類。 子類中構造函數先對父類的構造函數進行繼承;然後加上自己的特有屬性。 18,19行示例如何使用對象分別調用父類和子類的方法 上面代碼中6行示例如何在構造函數中操作公有屬性,實現類似全局計數功能。 10行定義的方法示例如何在父類中列印 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...