Spring之AOP配置

特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过。如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处: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

原文地址:https://www.cnblogs.com/mao2080/p/6803427.html