需要的依赖

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>

ASPECT


import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.org.apache.xpath.internal.operations.String;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; @Aspect
@Component
public class LogAspect { private final static Logger logger = LoggerFactory.getLogger(LogAspect.class); // * 表示所有返回类型 ..表示包及子包 * 表示所有类 .* 指类所有方法 (..) 代表所有参数
@Pointcut("execution(public * com.gailguo.demo.controller..*.*(..))")
public void controllerMethod() {
} @Before("controllerMethod()")
public void LogRequestInfo(JoinPoint joinPoint) throws Exception { logger.info("请求结果: Before " ); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest(); StringBuffer requestLog = new StringBuffer();
requestLog.append("请求信息:")
.append("URL = {" + request.getRequestURI() + "},\t")
.append("HTTP_METHOD = {" + request.getMethod() + "},\t")
.append("IP = {" + request.getRemoteAddr() + "},\t")
.append("CLASS_METHOD = {" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + "},\t"); if(joinPoint.getArgs().length == 0) {
requestLog.append("ARGS = {} ");
} else {
requestLog.append("ARGS = " + new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL)
.writeValueAsString(joinPoint.getArgs()[0]) + "");
} logger.info(requestLog.toString());
} @AfterReturning( pointcut = "controllerMethod()")
public void logResultVOInfo() throws Exception {
logger.info("请求结果: after return " );
} @After("controllerMethod()")
public void logAfter(JoinPoint joinPoint){
logger.info("请求结果: after " );
} @AfterThrowing("controllerMethod()")
public void logException(JoinPoint joinPoint){
logger.info("请求结果: after AfterThrowing " );
} @Around("controllerMethod()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable{ Object s=null;
if(joinPoint.getArgs().length>0){
s=joinPoint.getArgs()[0];
logger.info("Around: 打印传参 "+s.toString() );
}
logger.info("Around 1");
Object obj=joinPoint.proceed(new Object[]{"sss+"+s.toString()});
logger.info("Around 2");
return obj; } }

一个简单的controller

@RestController
@RequestMapping(path = "/aop")
public class MyController { @RequestMapping(path ="/test")
public String getTest(@RequestParam("id")String id){
return "111"+id;
}
}

  

Pointcut 执行表达式的格式

参考 

https://elim.iteye.com/blog/2395255

  

1: execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) 
除了返回类型模式(上面代码片断中的ret-type-pattern),

名字模式和参数模式以外,所有的部分都是可选的。

返回类型模式决定了方法的返回类型必须依次匹配一个连接点。

你会使用的最频繁的返回类型模式是 * ,它代表了匹配任意的返回类型。

一个全称限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。

你可以使用 * 通配符作为所有或者部分命名模式。

参数模式稍微有点复杂:() 匹配了一个不接受任何参数的方法, 而 (..) 匹配了一个接受任意数量参数的方法(零或者更多)。

模式 (*) 匹配了一个接受一个任何类型的参数的方法。

模式 (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型。

一些常见切入点表达式的例子

execution(public * *(..))  任意公共方法的执行;
execution(* set*(..))  任何一个以“set”开始的方法的执行; 
execution(* com.xyz.service.AccountService.*(..))   AccountService接口的任意方法的执行;
execution(* com.xyz.service.*.*(..))  定义在service包里的任意方法的执行;
execution(* com.xyz.service..*.*(..))  定义在service包或者子包里的任意方法的执行;

2. within 是用来指定类型的,指定类型中的所有方法将被拦截

3. bean 

bean用于匹配当调用的是指定的Spring的某个bean的方法时。

“bean(abc)”匹配Spring Bean容器中id或name为abc的bean的方法调用。

“bean(user*)”匹配所有id或name为以user开头的bean的方法调用。

@Component
public class TestInfo { Logger logger= LoggerFactory.getLogger(TestInfo.class); public void testInfo(){
logger.info("这里是testInfo 方法");
}
}

  

  @Pointcut("bean(testInfo)")
public void controllerMethod2(){ }

  

 @Around("controllerMethod2()")
public Object logAround2(ProceedingJoinPoint joinPoint) throws Throwable{ logger.info("Around testInfo 1");
Object obj=joinPoint.proceed();
logger.info("Around testInfo 2");
return obj; }

  

  @Autowired
TestInfo info; @RequestMapping(path ="/test")
public String getTest(@RequestParam("id")String id){
info.testInfo();
return "111"+id;
}

  

最新文章

  1. 关于解决asp.net mvc网站页面Banner图片即时更换css里背景图片url相对路径问题的新方案
  2. android 底层入门开发(二)
  3. ios cell展示可滑动的图片
  4. Haproxy配置支持https获取用户IP地址
  5. Django 学习笔记之四 QuerySet常用方法
  6. [topcoder]FoxAndChess
  7. ThinkPHP HTML标签代码和UBB互相转换
  8. PHP面试题之优化
  9. FZU Problem 2169 shadow
  10. GB2312引进和使用的字体
  11. Google Offer的经历+内推
  12. OpenGL多视口
  13. Kafka学习-Producer和Customer
  14. Safe Area Layout Guide
  15. 超简单的jQuery前台分页,不需导包
  16. .net mvc 上传头像
  17. java idea 代码规范插件
  18. win10系统桌面快捷键图标异常解决方法
  19. kbengine学习1 安装
  20. 【计算机网络】 网络体系结构分类: 客户机/服务器体系和P2P

热门文章

  1. Vivado debug异常现象
  2. UCOSIII钩子函数
  3. MySQL Hardware--FIO压测
  4. Android笔记(七十二) Style和Theme
  5. 将excel中的数据转为json格式
  6. 阿里巴巴开源性能监控神器Arthas jvm
  7. 通过Nginx实现一个简单的网站维护通知页面
  8. SoC的设计变的如此复杂和高成本
  9. 《CoderXiaoban》第八次团队作业:Alpha冲刺 2
  10. memcached的缺点