第一篇文章中,我貼了2段代碼,第一個是原生態的,第2段是我指定了接口定義規範,使用AOP技術以後最終交付的代碼,從15行到一行,本身感覺一下。今天來講說你們關注的AOP如何實現。java
先說說Controller規範,主要的內容是就是接口定義裏面的內容,你只要遵循裏面的規範,controller就問題不大,除了這些,還有另外的幾點:程序員
緣由見個人接口定義這個貼。沒有統一格式,AOP沒法玩。express
ResultBean/PageResultBean是controller專用的,不容許日後傳!json
Controller作參數格式的轉換,不容許把json,map這類對象傳到services去,也不容許services返回json、map。網絡
通常狀況下!寫過代碼都知道,map,json這種格式靈活,可是可讀性差,若是放業務數據,每次閱讀起來都比較困難。定義一個bean看着工做量多了,但代碼清晰多了。函數
主要是可讀性問題。通常狀況下。post
日誌在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了:
分頁的PageResultBean大同小異,你們本身依葫蘆畫瓢本身完成就行了。
貼一個簡單的controller(左邊的箭頭表示AOP攔截了)。請對比程序員你爲何這麼累?裏面原來的代碼查看,沒有對比就沒有傷害。
最後說一句,先有統一的接口定義規範,而後有AOP實現。先有思想再有技術。技術不是關鍵,AOP技術也很簡單,這個帖子的關鍵點不是技術,而是習慣和思想,不要撿了芝麻丟了西瓜。網絡上講技術的貼多,講習慣、風格的少,這些都是我工做多年的行之有效的經驗之談,望有緣人珍惜。