已經正式從NET轉型JAVA。今後開始多寫一點JAVA相關的文章。
因爲已經正式轉Java了,所以,對於Java的一些判斷,應該就比以前更準確了。總得來說,java有好的東西,有不好的東西,就語言本身和java的常用組件來講,並不能判斷,java比其他語言高一個檔次,當然,也不會低一個檔次。應該跟其他語言是一個段位的。
但java的調試,確實是比較花費時間,他做不到編譯成功後,就能運行成功。這裏有註解的問題,有maven的問題,有組件版本的問題。總之,檢測的非常不好,非常浪費時間。
java的好處就是,團隊成員比較多,畢竟開發起來真的很廢人。但好處也在這裏,人多,代表着,1,大家的壓力都不大,人多壓力就會分散。2,功能和性能有時間做的更優秀,人多就是工時多。
而且Java工資確實相對比其他語言高。
總體來說,java是比較幸福的。
開始正文
Aspectj提供一種在字符串裏編程的模式,即在字符串裏寫函數,然後程序啓動的時候會動態的把字符串裏的函數給執行了。
例如:
"execution(* *(..))"
這裏的execution就是一個函數,我們調用它,然後傳遞的參數是【* *(..)】。
execution: 用於匹配方法執行的連接點; execution(public * *(..)) ==> 匹配所有目標類的public方法,第一個*代表返回類型,第二個*代表方法名,而..代表任意入參的方法。 execution(* com.oysept.springboot.controller..*.*(..)) ==> 該包及所有子包下任何類的任何方法。 execution(* com.oysept.springboot.controller.*(..)) ==> 該包下任何類的任何方法。 execution(* com.oysept.springboot.controller.AspectJController.*(..)) ==> 該包下AspectJController類的任何方法。 execution(* com..*.*Controller.method*(..)) ==> 匹配包名前綴爲com的任何包下類名後綴爲Controller的方法,方法名必須以method爲前綴。 execution(* *To(..)) ==> 匹配目標類所有以To爲後綴的方法。 注: 該方法只是爲了聲明一個公共的環繞通知,也可以直接在具體方法配置,如: @Around("execution(* com.oysept.springboot.controller..*.*(..))")
@Before和@AfterReturning
/** * @Before:定義了前置通知方法。打印出入參 * @AfterReturning:定義了後置返回通知方法。打印出入參、返參 */ @Slf4j @Aspect @Component public class AopAspect_Basic { @Before("execution(public * com.k.tender.controller.business.user.UserController.*(..))") public void doBefore(JoinPoint point){ String methodName = point.getSignature().getName(); List<Object> args = Arrays.asList(point.getArgs()); log.info("調用前連接點方法爲:" + methodName + ",參數爲:" + args); } @AfterReturning(value = "execution(public * com.k.tender.controller.business.user.UserController.*(..))", returning = "returnValue") public void doAfterReturning(JoinPoint point, Object returnValue){ String methodName = point.getSignature().getName(); List<Object> args = Arrays.asList(point.getArgs()); log.info("調用前連接點方法爲:" + methodName + ",參數爲:" + args + ",返回值爲:" + returnValue); } }
如上代碼,我們使用了@Before和@AfterReturning註解,在UserController調用前和後,分別埋了點,並輸出了函數的入參和出參。
@Pointcut
@Pointcut("execution(public * com.k.tender.controller.business.tender.TenderController.*(..))") public void doPointCut() { } @Before("doPointCut()") public void doBefore(JoinPoint point){ String methodName = point.getSignature().getName(); List<Object> args = Arrays.asList(point.getArgs()); log.info("調用前連接點方法爲:" + methodName + ",參數爲:" + args); } @AfterReturning(value = "doPointCut()", returning = "returnValue") public void doAfterReturning(JoinPoint point, Object returnValue){ String methodName = point.getSignature().getName(); List<Object> args = Arrays.asList(point.getArgs()); log.info("調用前連接點方法爲:" + methodName + ",參數爲:" + args + ",返回值爲:" + returnValue); }
對註解埋點
有時候,我們希望編寫一個註解,然後讓有該註解的函數,都被攔截,那麼就可以使用Aspectj的註解埋點模式。
代碼如下:
@Slf4j @Aspect @Component public class AopAspect_Annotation { @Before("@annotation(com.k.tender.aop.MyAop)") public void doBefore(JoinPoint point){ String methodName = point.getSignature().getName(); List<Object> args = Arrays.asList(point.getArgs()); log.info("調用前連接點方法爲:" + methodName + ",參數爲:" + args); } @AfterReturning(value ="@annotation(com.k.tender.aop.MyAop)", returning = "returnValue") public void doAfterReturning(JoinPoint point, Object returnValue){ String methodName = point.getSignature().getName(); List<Object> args = Arrays.asList(point.getArgs()); log.info("調用前連接點方法爲:" + methodName + ",參數爲:" + args + ",返回值爲:" + returnValue); } }
String value() default "自定義註解攔截";
}
如果覺得寫註解的命名空間麻煩,也可以這樣寫:
@Before("@annotation(apiOperation)") public void doBefore(JoinPoint point, MyAopAsyncTask apiOperation) { String methodName = point.getSignature().getName(); List<Object> args = Arrays.asList(point.getArgs()); log.info("調用前連接點方法爲:" + methodName + ",參數爲:" + args); }
還可以將註解和前面的excution函數結合寫:
@Before("execution(public * com.k..*.*(..)) && @annotation(apiOperation)") public void doBefore(JoinPoint point, MyAopAsyncTask apiOperation) throws NoSuchMethodException { String methodName = point.getSignature().getName(); List<Object> args = Arrays.asList(point.getArgs()); log.info("調用前連接點方法爲:" + methodName + ",參數爲:" + args); }
有時候我們的攔截會觸發多次,這個具體原因調查起來很麻煩,我們也可以這樣解決,代碼如下:
private volatile long hashcode = 0;//應對重複觸發 @Before("execution(public * com.k..*.*(..)) && @annotation(apiOperation)") public void doBefore(JoinPoint point, MyAopAsyncTask apiOperation) throws NoSuchMethodException { if (hashcode != point.getTarget().hashCode()) { log.info("========doBefore========"); ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); String method = request.getMethod(); } }
使用hashcode來過濾多次攔截。
----------------------------------------------------------------------------------------------------
到此,Android裏使用AspectJ實現AOP就介紹完了。
----------------------------------------------------------------------------------------------------
注:此文章爲原創,任何形式的轉載都請聯繫作者獲得授權並註明出處!
若您覺得這篇文章還不錯,請點擊下方的【推薦】,非常感謝!
https://www.cnblogs.com/kiba/p/18027435