編碼習慣之Controller規範

第一篇文章中,我貼了2段代碼,第一個是原生態的,第2段是我指定了接口定義規範,使用AOP技術以後最終交付的代碼,從15行到一行,本身感覺一下。今天來講說你們關注的AOP如何實現。java

先說說Controller規範,主要的內容是就是接口定義裏面的內容,你只要遵循裏面的規範,controller就問題不大,除了這些,還有另外的幾點:程序員

  1. 全部函數返回統一的ResultBean/PageResultBean格式

緣由見個人接口定義這個貼。沒有統一格式,AOP沒法玩。express

  1. ResultBean/PageResultBean是controller專用的,不容許日後傳!json

  2. Controller作參數格式的轉換,不容許把json,map這類對象傳到services去,也不容許services返回json、map。網絡

通常狀況下!寫過代碼都知道,map,json這種格式靈活,可是可讀性差,若是放業務數據,每次閱讀起來都比較困難。定義一個bean看着工做量多了,但代碼清晰多了。函數

  1. 參數中通常狀況不容許出現Request,Response這些對象

主要是可讀性問題。通常狀況下。post

  1. 不須要打印日誌

日誌在AOP裏面會打印,並且個人建議是大部分日誌在Services這層打印。this

規範裏面大部分是 不要作的項多,要作的比較少,落地比較容易。spa

ResultBean定義帶泛型,使用了lombok。日誌

@Data
public class ResultBean<T> implements Serializable {

  private static final long serialVersionUID = 1L;

  public static final int NO_LOGIN = -1;

  public static final int SUCCESS = 0;

  public static final int FAIL = 1;

  public static final int NO_PERMISSION = 2;

  private String msg = "success";

  private int code = SUCCESS;

  private T data;

  public ResultBean() {
    super();
  }

  public ResultBean(T data) {
    super();
    this.data = data;
  }

  public ResultBean(Throwable e) {
    super();
    this.msg = e.toString();
    this.code = FAIL;
  }
}

AOP代碼,主要就是打印日誌和捕獲異常,異常要區分已知異常和未知異常,其中未知的異常是咱們重點關注的,能夠作一些郵件通知啥的,已知異常能夠再細分一下,能夠不一樣的異常返回不一樣的返回碼:

public class ControllerAOP {
  private static final Logger logger = LoggerFactory.getLogger(ControllerAOP.class);

  public Object handlerControllerMethod(ProceedingJoinPoint pjp) {
    long startTime = System.currentTimeMillis();

    ResultBean<?> result;

    try {
      result = (ResultBean<?>) pjp.proceed();
      logger.info(pjp.getSignature() + "use time:" + (System.currentTimeMillis() - startTime));
    } catch (Throwable e) {
      result = handlerException(pjp, e);
    }

    return result;
  }

  private ResultBean<?> handlerException(ProceedingJoinPoint pjp, Throwable e) {
    ResultBean<?> result = new ResultBean();

    // 已知異常
    if (e instanceof CheckException) {
      result.setMsg(e.getLocalizedMessage());
      result.setCode(ResultBean.FAIL);
    } else {
      logger.error(pjp.getSignature() + " error ", e);

      result.setMsg(e.toString());
      result.setCode(ResultBean.FAIL);

     // 未知異常是應該重點關注的,這裏能夠作其餘操做,如通知郵件,單獨寫到某個文件等等。
    }

    return result;
  }
}

AOP配置:(關於用java代碼仍是xml配置,這裏我傾向於xml配置,由於這個會不按期改動)

<!-- aop -->
  <aop:aspectj-autoproxy />
  <beans:bean id="controllerAop" class="xxx.common.aop.ControllerAOP" />

  <aop:config>
    <aop:aspect id="myAop" ref="controllerAop">
      <aop:pointcut id="target"
        expression="execution(public xxx.common.beans.ResultBean *(..))" />
      <aop:around method="handlerControllerMethod" pointcut-ref="target" />
    </aop:aspect>
  </aop:config>

如今知道爲何要返回統一的一個ResultBean了:

  • 爲了統一格式
  • 爲了應用AOP
  • 爲了包裝異常信息

分頁的PageResultBean大同小異,你們本身依葫蘆畫瓢本身完成就行了。

貼一個簡單的controller(左邊的箭頭表示AOP攔截了)。請對比程序員你爲何這麼累?裏面原來的代碼查看,沒有對比就沒有傷害。

最後說一句,先有統一的接口定義規範,而後有AOP實現。先有思想再有技術。技術不是關鍵,AOP技術也很簡單,這個帖子的關鍵點不是技術,而是習慣和思想,不要撿了芝麻丟了西瓜。網絡上講技術的貼多,講習慣、風格的少,這些都是我工做多年的行之有效的經驗之談,望有緣人珍惜。

相關文章
相關標籤/搜索