Spring AOP运用---记录方法调用与结果日志
来源:互联网 发布:阿里云服务器 密钥 编辑:程序博客网 时间:2024/06/05 15:45
Spring AOP运用—记录方法调用与结果日志
AOP(Aspect Oriented Programming),即面向切面编程,更多的理论知识可以参考http://jinnianshilongnian.iteye.com/blog/1418596,本文主要针对掌握了一定的理论知识基础上,如何在实际项目中运用AOP。
在进行互联网项目开发过程中,尤其是微服务开发模式下,各模块(或web服务)之间会有频繁的调用过程,为了后续的问题排查与定位,往往需要在方法调用入口与出口处记录日志,如下:
logger.info("接收xxxxxx参数{}",JSON.toJSONString(request));doSomething();logger.info("接收XXXXXX返回{}",JSON.toJSONString(result));
这样实现需要对每个方法添加类似代码,如果采用AOP实现,则方法体内仅实现具体的业务逻辑即可,不用再额外添加与业务无关的通用代码。
AOP编程基本流程
1、定义业务切面(所谓”切面”,简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。)
2、定义切入点,一个切入点可能横切多个业务组件(即在哪些地方,对哪些方法进行拦截)
3、定义处理动作,就是在AOP框架为业务切面织入的处理动作
AOP编程实战
下面将针对本文开头提到的采用AOP进行日志记录的完整实现。
定义日志处理切面
import com.alibaba.fastjson.JSON;import org.aspectj.lang.JoinPoint;public class LogHandler { /** * 打印方法入参 * @param jp */ public void methodParam(JoinPoint jp){ System.out.println("---method " + jp.getSignature().toShortString() +"invoked,param is :" + JSON.toJSONString(jp.getArgs())); } /** * 打印方法返回结果 * @param jp * @param retVal */ public void methodResult(JoinPoint jp,Object retVal){ System.out.println("---method " + jp.getSignature().toShortString() +"invoked,result is :" +retVal); } /** * 打印异常 * @param jp * @param exception */ public void methodException(JoinPoint jp, Exception exception){ System.out.println("---method " + jp.getSignature().toShortString() +"invoked,exception " + "is :" + exception.getMessage()); }}
LogHandler 类中定义了3个切面处理,methodParam用于打印方法的入参,methodResult打印方法的返回结果,methodException打印异常日志。
定义切入点
在XML配置文件中进行配置
<aop:pointcut id="pointcut" expression="execution(* service.*.*(..))"/>
表示对service包下的所有方法有效。
定义处理动作
<aop:aspect ref="logHandler"> <aop:before pointcut-ref="pointcut" method="methodParam"/> <aop:after-returning pointcut-ref="pointcut" method="methodResult" returning = "retVal"/> <aop:after-throwing pointcut-ref="pointcut" method="methodException" throwing = "exception"/> </aop:aspect>
完整的XML配置如下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> <aop:aspectj-autoproxy /> <context:annotation-config /> <context:component-scan base-package="service"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 支持异步方法执行 --> <task:annotation-driven /> <bean id="helloWorldService" class="service.impl.HelloWorldServiceImpl"/> <bean id="logHandler" class="aop.LogHandler"/> <aop:config> <aop:pointcut id="pointcut" expression="execution(* service.*.*(..))"/> <aop:aspect ref="logHandler"> <aop:before pointcut-ref="pointcut" method="methodParam"/> <aop:after-returning pointcut-ref="pointcut" method="methodResult" returning = "retVal"/> <aop:after-throwing pointcut-ref="pointcut" method="methodException" throwing = "exception"/> </aop:aspect> </aop:config></beans>
测试
在service包下创建HelloWorldService接口以及service.impl包下创建实现该接口的HelloWorldServiceImpl类
HelloWorldService.java
public interface HelloWorldService { public String methodLog(String obj);}
HelloWorldServiceImpl.java
public class HelloWorldServiceImpl implements HelloWorldService { public String methodLog(String obj) { Random random = new Random(System.currentTimeMillis()); return String.valueOf(random.nextInt()); }}
创建Junit进行测试
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {"classpath*:config/applicationContext.xml"})public class AopTest { @Resource private HelloWorldService helloWorldService; @Test public void methodLogTest_nomal(){ helloWorldService.methodLog("nomal"); }}
测试结果:
---method HelloWorldService.methodLog(..)invoked,param is :["nomal"]---method HelloWorldService.methodLog(..)invoked,result is :-1928245693
AOP在项目中运用比较多的有方法权限验证、参数验证方法耗时统计处理等。具体使用方法类似。更多可参看Spring的官方文档。
- Spring AOP运用---记录方法调用与结果日志
- spring aop 日志记录
- Spring AOP记录日志!
- Spring AOP记录日志! .
- spring aop记录日志
- Spring AOP 记录日志
- Spring AOP日志记录
- Spring AOP 记录日志
- spring AOP--记录日志
- Spring AOP记录系统日志
- spring aop记录日志,Log4j
- Spring AOP 完成日志记录
- Spring AOP 完成日志记录
- Spring AOP 完成日志记录
- Spring AOP 完成日志记录
- Spring AOP 系统日志记录
- Spring AOP 完成日志记录
- Spring AOP实现日志记录
- java 注解详解,自定义注解
- badgeValue的设置和使用
- 七牛(7.0.3)工具类,java上传下载demo
- sonarqube中文插件安装
- MySQL常用命令 一
- Spring AOP运用---记录方法调用与结果日志
- for的图形练习与转义字符注意点
- ORACLE Scheduler特性(10)管理Chains
- 微信小程序 事件冒泡(十二)
- 质数中的质数(质数筛法)
- http 请求
- 数据库中事务的四大特性(ACID) and 事务的隔离级别。
- 交叉编译时候如何设置连接库的搜索路径
- Codeforces Round #426 (Div. 2) C. The Meaningless Game