spring boot使用aop攔截Controller和Service以方便除錯
阿新 • • 發佈:2018-12-30
除錯的時候,經常需要看每個函式的輸入輸出,以前每次都是System.out.println
輸出,除錯完後還要刪掉,要是每次都能自己輸出函式的輸入輸出就好了。
在網上找了一通,結合《Spring 實戰》寫了一個自己用的切面
- BaseAspect
public abstract class BaseAspect { protected Object process(ProceedingJoinPoint pjp, StringBuilder sb) throws Throwable { //獲取連線點目標類名 String targetName = pjp.getTarget().getClass().getName(); //獲取連線點簽名的方法名 String methodName = pjp.getSignature().getName(); //獲取連線點引數 Object[] args = pjp.getArgs(); //根據連線點類的名字獲取指定類 Class targetClass = Class.forName(targetName); //獲取類裡面的方法 Method[] methods = targetClass.getMethods(); Object object = pjp.proceed(); sb.append(targetClass.getCanonicalName()) .append(methodName) .append(JSON.toJSONString(args)) .append(object); return object; } }
- ControllerDebugAspect
/** * Controller除錯用切面,可以快速瞭解輸入輸出是 */ @Aspect @Component @Slf4j public class ControllerDebugAspect extends BaseAspect{ @Pointcut("execution(* api.*.controller.*.*(..)) || execution(* api.controller.*.*(..))") public void Pointcut() { } @Around("Pointcut()") public Object Around(ProceedingJoinPoint pjp) throws Throwable { StringBuilder sb = new StringBuilder(); Object object = process(pjp, sb); logger.debug(sb.toString()); return object; } }
- ServiceDebugAspect
@Aspect @Component @Slf4j public class ServiceDebugAspect extends BaseAspect{ // @Pointcut("@annotation(org.springframework.web.bind.annotation.RestController) || @annotation(org.springframework.stereotype.Service)") @Pointcut("execution(* api.*.service.impl.*.*(..)) || execution(* api.service.impl.*.*(..))") public void Pointcut() { } @Around("Pointcut()") public Object Around(ProceedingJoinPoint pjp) throws Throwable { StringBuilder sb = new StringBuilder(); Object object = process(pjp, sb); logger.debug(sb.toString()); return object; } }
後面兩個其實是一樣的。
在除錯的時候,IDEA有一個按鈕
每次寫完Pointcut表示式,按一下可以知道有哪些方法會生效
除了程式碼,還有兩個地方
一個是application.properties檔案
#aop
spring.aop.proxy-target-class=true
spring.aop.auto=true
一個是在@SpringBootApplication
所在的類上寫註解
@EnableAspectJAutoProxy(exposeProxy=true)
後來測了一下,去掉註解也是可以的
看了一下註解原始碼
public @interface EnableAspectJAutoProxy {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}.
*/
boolean proxyTargetClass() default false;
/**
* Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
* Off by default, i.e. no guarantees that {@code AopContext} access will work.
* @since 4.3.1
*/
boolean exposeProxy() default false;
}
使用註解和寫application.properties檔案應該是等價的