aop的概念不少,好比切點,通知,鏈接點,引入,織入等;實際上這是一種約定的流程;
https://github.com/carterbrot...java
也是按照必定規則,按照必定 流程來約定編程的;
提取固定 流程,把變化的部分織入到流程中便可;git
鏈接點(join point) : 即方法github
切點 (point cut): 鏈接點的範圍,哪些方法;spring
通知(advice): 分爲前置通知,後置通知,環繞通知,正常返回通知,異常返回通知數據庫
目標對象(target) :被代理對象編程
引入(introduction): 引入新的類和方法,加強現有的bean的功能springboot
織入(weaving): 經過代理技術,爲原有對象生成代理對象this
切面(aspect) : 能夠定義切點,各種通知和引用的內容google
@Aspect 申明切面spa
通知裏面放切點:
@Before 前置通知
@After 後置通知
@AfterReturn
@AfterThrowning
@Around
@Pointcut 定義切點
切點的指示器:
通知中的參數:
ProceedingJoinPoint jp 鏈接點信息
jp.proceed();//執行原來的方法
spring採用兩種動態代理方式,jdk的動態代理和cglib的動態代理,若是被代理類沒有實現接口,spring會切換爲cglib的動態代理;
多個切面,使用@Order(value=x) 來定義順序,前置通知從升序執行,後置通知降序執行;
例子:
package com.lifesense.ihs.tianansp.admin.interceptor; import com.google.common.base.Strings; import com.lifesense.ihs.tianansp.admin.core.TaAdminRestContext; import com.lifesense.opensource.commons.utils.JsonUtils; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Service; import org.springframework.util.StopWatch; import java.lang.reflect.Method; /** * aop */ @Aspect @Service @Order(0) @Slf4j public class ServiceInterceptor { @Pointcut("execution(public * com.lifesense.ihs.**.admin.manager..*.*(..))") public void pointcut() { } private String serviceName() { return "tiananspadmin"; } @Around("pointcut()") public Object around(ProceedingJoinPoint pjp) throws Throwable { StopWatch stopWatch = new StopWatch(); Method method = ((MethodSignature) pjp.getSignature()).getMethod(); final String methodName = method.getDeclaringClass().getCanonicalName().concat(".").concat(method.getName()); stopWatch.start(methodName); Object[] args = pjp.getArgs(); String requestId = TaAdminRestContext.get().getRequestId(); Object returnObj = null; try { returnObj = pjp.proceed(); } catch (Exception ex) { String message = String.format("[%s]服務發生系統錯誤:%s", this.serviceName(), ex.getMessage()); log.error("{}, method:{},args:{} , ServiceContext:{}", message, methodName, JsonUtils.toJson(args), TaAdminRestContext.get(), ex); throw ex; } finally { stopWatch.stop(); if (log.isDebugEnabled()) { log.debug("timecost_requestId:{} , args:{},returnObj:{},\n{}:", requestId, JsonUtils.toJson(args), JsonUtils.toJson(returnObj), stopWatch.prettyPrint()); } } return returnObj; } }
原創不易,轉載請註明出處,歡迎溝通交流。