特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过。如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/mao2080/
1、什么是AOP?
AOP全名Aspect-Oriented Programming,中文直译为面向切面(方面)编程,当前已经成为一种比较成熟的编程思想,可以用来很好的解决应用系统中分布于各个模块的交叉关注点问题。在轻量级的J2EE中应用开发中,使用AOP来灵活处理一些具有横切性质的系统级服务,如系统日志、异常处理、事务处理、安全检查、缓存、对象池管理等,已经成为一种非常适用的解决方案。 AOP中比较重要的概念有:Aspect、JoinPoint、PonitCut、Advice、Introduction、Weave、Target Object、Proxy Object等。
本文主要用来做接入层日志收集,接入层异常统一处理,以及后续性能分析。
2、如何使用AOP?
1 package com.mao; 2 import org.apache.commons.logging.Log; 3 import org.apache.commons.logging.LogFactory; 4 import org.aspectj.lang.ProceedingJoinPoint; 5 import org.aspectj.lang.annotation.Around; 6 import org.aspectj.lang.annotation.Aspect; 7 import org.aspectj.lang.annotation.Pointcut; 8 import org.springframework.stereotype.Component; 9 10 import com.mao.util.JsonUtil; 11 12 /** 13 * 14 * 项目名称: 15 * 模块名称: 16 * 功能描述: 17 * 创建人: mao2080@sina.com 18 * 创建时间:2017年5月3日 下午6:34:37 19 * 修改人: mao2080@sina.com 20 * 修改时间:2017年5月3日 下午6:34:37 21 */ 22 @Aspect 23 @Component 24 public class LogerInterceptor { 25 26 /**日志*/ 27 private static final Log logger = LogFactory.getLog(LogerInterceptor.class); 28 29 /** 30 * 31 * 描述:切入点(Controller层) 32 * @author mao2080@sina.com 33 * @created 2017年5月3日 下午4:49:47 34 * @since 35 */ 36 @Pointcut("execution(public * com.web.controller.*.*(..))") 37 public void controllerAround() { 38 39 } 40 41 /** 42 * 43 * 描述:执行切面环绕(Controller层) 44 * @author mao2080@sina.com 45 * @created 2017年5月3日 下午4:52:03 46 * @since 47 * @param joinPoint 切入点上下文,包含目标方法和参数等 48 * @return 目标方法执行的结果 49 * @throws Throwable 50 */ 51 @Around("controllerAround()") 52 public Object doControllerAround(ProceedingJoinPoint joinPoint) throws Throwable { 53 //获取类名 54 String className = joinPoint.getSignature().toShortString(); 55 //获取入参 56 Object inputArgs = joinPoint.getArgs(); 57 //入参日志 58 logger.info(className+" input:"+JsonUtil.toJson(inputArgs)); 59 //记录时间 60 long sta = System.currentTimeMillis(); 61 //调用方法 62 Object result = null; 63 try { 64 result = joinPoint.proceed(); 65 } catch (Exception e) { 66 logger.error(className+" exception: "+e.toString()+", input: "+JsonUtil.toJson(inputArgs)); 67 result = new ResObject(201, "系统出现异常"+e.getMessage()); 68 } 69 //出参日志 70 logger.info(className+" output:"+JsonUtil.toJson(result)+", execute time:"+(System.currentTimeMillis() - sta)+"ms"); 71 return result; 72 } 73 74 }
3、ResObject
1 package com.mao; 2 3 import java.io.Serializable; 4 5 /** 6 * 7 * 项目名称: 8 * 模块名称: 9 * 功能描述: 10 * 创建人: mao2080@sina.com 11 * 创建时间:2017年5月3日 下午6:37:11 12 * 修改人: mao2080@sina.com 13 * 修改时间:2017年5月3日 下午6:37:11 14 */ 15 public class ResObject implements Serializable{ 16 17 /**序列号*/ 18 private static final long serialVersionUID = 589903502110209046L; 19 20 /**返回代码*/ 21 private int code = 200; 22 23 /**返回信息*/ 24 private String desc = "Success."; 25 26 /**返回数据*/ 27 private Object data; 28 29 /** 30 * 31 * 构建函数 32 * @author mao2080@sina.com 33 * @created 2017年3月24日 下午4:25:23 34 * @since 35 */ 36 public ResObject() { 37 38 } 39 40 /** 41 * 42 * 描述:构造函数 43 * @author mao2080@sina.com 44 * @created 2017年4月18日 下午3:32:26 45 * @since 46 * @param data 数据 47 */ 48 public ResObject(Object data) { 49 super(); 50 this.data = data; 51 } 52 53 /** 54 * 55 * 构建函数 56 * @author mao2080@sina.com 57 * @created 2017年3月24日 下午4:25:35 58 * @since 59 * @param code 返回代码 60 * @param desc 返回信息 61 */ 62 public ResObject(int code, String desc) { 63 super(); 64 this.code = code; 65 this.desc = desc; 66 } 67 68 /** 69 * 70 * 构建函数 71 * @author mao2080@sina.com 72 * @created 2017年3月24日 下午4:25:39 73 * @since 74 * @param code 返回代码 75 * @param desc 返回信息 76 * @param data 返回数据 77 */ 78 public ResObject(int code, String desc, Object data) { 79 super(); 80 this.code = code; 81 this.desc = desc; 82 this.data = data; 83 } 84 85 public Object getData() { 86 return data; 87 } 88 89 public void setData(Object data) { 90 this.data = data; 91 } 92 93 public int getCode() { 94 return code; 95 } 96 97 public void setCode(int code) { 98 this.code = code; 99 } 100 101 public String getDesc() { 102 return desc; 103 } 104 105 public void setDesc(String desc) { 106 this.desc = desc; 107 } 108 109 }
4、访问结果
1 2017-05-03 18:41:51,633 (http-bio-8080-exec-4) [INFO - com.mao.LogerInterceptor.doControllerAround(LogerInterceptor.java:58)] LoginController.login(..) input:["mao","123456"] 2 2017-05-03 18:41:51,737 (http-bio-8080-exec-4) [INFO - com.mao.LogerInterceptor.doControllerAround(LogerInterceptor.java:70)] LoginController.login(..) output:{"code":200,"data":{"token":"64501f456ec667d420ac2610b4fd81e1",},"desc":"Success."}, execute time:103ms
5、配置注意事项
由于使用了springmvc,导致配置spring aop时没有起作用,最后需要在spring配置文件中加入这项配置。
<aop:aspectj-autoproxy proxy-target-class="false"/>
6、参考网站
http://blog.csdn.net/luoshenfu001/article/details/5816408/
http://outofmemory.cn/code-snippet/3025/spring-AOP-Around-Before-After-differentiate