主要的內容是就是接口定義裏面的內容,你只要遵循裏面的規範,controller就問題不大,除了這些,還有另外的幾點:java
1 全部函數返回統一的ResultBean/PageResultBean格式程序員
緣由見個人接口定義這個貼。沒有統一格式,AOP沒法玩。express
2 ResultBean/PageResultBean是controller專用的,不容許日後傳!json
3 Controller作參數格式的轉換,不容許把json,map這類對象傳到services去,也不容許services返回json、map。網絡
通常狀況下!寫過代碼都知道,map,json這種格式靈活,可是可讀性差,若是放業務數據,每次閱讀起來都比較困難。定義一個bean看着工做量多了,但代碼清晰多了。函數
4 參數中通常狀況不容許出現Request,Response這些對象this
主要是可讀性問題。通常狀況下。日誌
5 不須要打印日誌code
日誌在AOP裏面會打印,並且個人建議是大部分日誌在Services這層打印。xml
規範裏面大部分是 不要作的項多,要作的比較少,落地比較容易。
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 if (e instanceof UnloginException) { result.setMsg("Unlogin"); result.setCode(ResultBean.NO_LOGIN); } else { logger.error(pjp.getSignature() + " error ", e); //TODO 未知的異常,應該格外注意,能夠發送郵件通知等 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了:
分頁的PageResultBean大同小異,你們本身依葫蘆畫瓢本身完成就行了。
貼一個簡單的controller(左邊的箭頭表示AOP攔截了)。請對比 程序員你爲何這麼累?裏面原來的代碼查看,沒有對比就沒有傷害。
先有統一的接口定義規範,而後有AOP實現。先有思想再有技術。技術不是關鍵,AOP技術也很簡單,這個帖子的關鍵點不是技術,而是習慣和思想,不要撿了芝麻丟了西瓜。網絡上講技術的貼多,講習慣、風格的少,這些都是我工做多年的行之有效的經驗之談,望有緣人珍惜。