在看看实现方法之前,我们先看下切面日志输出效果咋样:
从上图中可以看到,每个对于每个请求,开始与结束一目了然,并且打印了以下参数:
POST
, GET
, 还是 DELETE
等;怎么样?看上去效果还不错呢?接下来看看,我们要如何一步一步实现它呢?
在项目 pom.xml
文件中添加依赖:
<!-- aop 依赖 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency>
<!-- 用于日志切面中,以 json 格式打印出入参 --><dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version></dependency>
让我们来自定义一个日志注解,如下所示:
WebLog
;到这里,一个完整的自定义注解就定义完成了。
在配置 AOP 切面之前,我们需要了解下 aspectj
相关注解的作用:
切点定义好后,就是围绕这个切点做文章了:
接下来,定义一个 WebLogAspect.java
切面类,声明一个切点:
然后,定义 @Around
环绕,用于何时执行切点:
再来看看 @Before
方法:
看注释功能说明,因为注释说得还是比较清楚的!
最后,用 @After
来做个收尾:
我们在每个接口的最后,打印日志结束标志。最后再看下项目包结构:
到这里,切面相关的代码就完成了!
因为我们的切点是自定义注解 @WebLog
, 所以我们仅仅需要在 Controller 控制器的每个接口方法添加 @WebLog 注解即可,如果我们不想某个接口打印出入参日志,不加注解就可以了:
是好使的!不论是单文件上传,抑或是多文件上传,切面日志均运行良好,这里测试的东西,小哈就不贴出来了。有兴趣的小伙伴可以试试!
对于那些性能要求较高的应用,不想在生产环境中打印日志,只想在开发环境或者测试环境中使用,要怎么做呢?我们只需为切面添加 @Profile
就可以了,如下图所示:
这样就指定了只能作用于 dev
开发环境和 test
测试环境,生产环境 prod
是不生效的!
假设说我们的服务中不止定义了一个切面,比如说我们针对 Web 层的接口,不止要打印日志,还要校验 token 等。要如何指定切面的优先级呢?也就是如何指定切面的执行顺序?
我们可以通过 @Order(i)
注解来指定优先级,注意:i 值越小,优先级则越高。
假设说我们定义上面这个日志切面的优先级为 @Order(10)
, 然后我们还有个校验 token
的切面 CheckTokenAspect.java
,我们定义为了 @Order(11)
, 那么它们之间的执行顺序如下:
我们可以总结一下:
@Order
从小到大被执行,也就是说越小的优先级越高;@Order
从大到小被执行,也就是说越大的优先级越高;http://blog.didispace.com/springbootaoplog
https://github.com/weiwosuoai/spring-boot-tutorial/tree/master/spring-boot-aop-web-request