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

 package com.mao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; import com.mao.util.JsonUtil; /**
*
* 项目名称:
* 模块名称:
* 功能描述:
* 创建人: mao2080@sina.com
* 创建时间:2017年5月3日 下午6:34:37
* 修改人: mao2080@sina.com
* 修改时间:2017年5月3日 下午6:34:37
*/
@Aspect
@Component
public class LogerInterceptor { /**日志*/
private static final Log logger = LogFactory.getLog(LogerInterceptor.class); /**
*
* 描述:切入点(Controller层)
* @author mao2080@sina.com
* @created 2017年5月3日 下午4:49:47
* @since
*/
@Pointcut("execution(public * com.web.controller.*.*(..))")
public void controllerAround() { } /**
*
* 描述:执行切面环绕(Controller层)
* @author mao2080@sina.com
* @created 2017年5月3日 下午4:52:03
* @since
* @param joinPoint 切入点上下文,包含目标方法和参数等
* @return 目标方法执行的结果
* @throws Throwable
*/
@Around("controllerAround()")
public Object doControllerAround(ProceedingJoinPoint joinPoint) throws Throwable {
//获取类名
String className = joinPoint.getSignature().toShortString();
//获取入参
Object inputArgs = joinPoint.getArgs();
//入参日志
logger.info(className+" input:"+JsonUtil.toJson(inputArgs));
//记录时间
long sta = System.currentTimeMillis();
//调用方法
Object result = null;
try {
result = joinPoint.proceed();
} catch (Exception e) {
logger.error(className+" exception: "+e.toString()+", input: "+JsonUtil.toJson(inputArgs));
result = new ResObject(201, "系统出现异常"+e.getMessage());
}
//出参日志
logger.info(className+" output:"+JsonUtil.toJson(result)+", execute time:"+(System.currentTimeMillis() - sta)+"ms");
return result;
} }

3、ResObject

 package com.mao;

 import java.io.Serializable;

 /**
*
* 项目名称:
* 模块名称:
* 功能描述:
* 创建人: mao2080@sina.com
* 创建时间:2017年5月3日 下午6:37:11
* 修改人: mao2080@sina.com
* 修改时间:2017年5月3日 下午6:37:11
*/
public class ResObject implements Serializable{ /**序列号*/
private static final long serialVersionUID = 589903502110209046L; /**返回代码*/
private int code = 200; /**返回信息*/
private String desc = "Success."; /**返回数据*/
private Object data; /**
*
* 构建函数
* @author mao2080@sina.com
* @created 2017年3月24日 下午4:25:23
* @since
*/
public ResObject() { } /**
*
* 描述:构造函数
* @author mao2080@sina.com
* @created 2017年4月18日 下午3:32:26
* @since
* @param data 数据
*/
public ResObject(Object data) {
super();
this.data = data;
} /**
*
* 构建函数
* @author mao2080@sina.com
* @created 2017年3月24日 下午4:25:35
* @since
* @param code 返回代码
* @param desc 返回信息
*/
public ResObject(int code, String desc) {
super();
this.code = code;
this.desc = desc;
} /**
*
* 构建函数
* @author mao2080@sina.com
* @created 2017年3月24日 下午4:25:39
* @since
* @param code 返回代码
* @param desc 返回信息
* @param data 返回数据
*/
public ResObject(int code, String desc, Object data) {
super();
this.code = code;
this.desc = desc;
this.data = data;
} public Object getData() {
return data;
} public void setData(Object data) {
this.data = data;
} public int getCode() {
return code;
} public void setCode(int code) {
this.code = code;
} public String getDesc() {
return desc;
} public void setDesc(String desc) {
this.desc = desc;
} }

4、访问结果

 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"]
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

Spring之AOP配置的更多相关文章

  1. Spring的AOP配置

    Spring的AOP配置 1.先写一个普通类: package com.spring.aop; public class Common {  public void execute(String us ...

  2. spring.net AOP配置基础

    在第一篇中,我们用配置代理工厂的方式实现了面向切面记日志的功能.非常便捷的实现了AOP,但当我们需要对多个切入点配置通知的时候就需要声明多个代理工厂,这样导致配置文件内容过多,配置过程也很繁琐.spr ...

  3. 学习 Spring (十三) AOP 配置

    Spring入门篇 学习笔记 Spring 所有的切面和通知器都必须放在一个 内(可以配置包含多个 元素),每一个 可以包含 pointcut, advisor 和 aspect 元素(它们必须按照这 ...

  4. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

  5. 使用Spring实现AOP(XML+注解)

    一.Spring对AOP的支持 AOP并不是Spring框架特有的,Spring只是支持AOP编程的框架之一,每一个框架对AOP的支持各有特点,有些AOP能够对方法的参数进行拦截,有些AOP对方法进行 ...

  6. Spring的aop思想

    1.AOP思想 (1)在解决中文乱码的应用: 一般情况下如果在Servlet中要解决中文乱码问题需要在每一个Servlet中书写解决乱码的代码,但是,在运用了过滤器之后,就不再需要每一个Servlet ...

  7. Java--简单的Spring AOP配置以及AOP事物管理,JDK/GCLib动态代理

    一.看一下简单的通过XML的AOP配置 1.首先创建一个简单的Student类 public class Student { private Integer age; private String n ...

  8. spring之aop概念和配置

    面向切面的一些概念: 简单说: 连接点就一些方法,在这些方法基础上需要额外的一些业务需求处理. 切入点就是方法所代表的功能点组合起来的功能需求. 通知就是那些额外的操作. 织入就是使用代理实现整个切入 ...

  9. spring aop配置及用例说明(1)

    欢迎转载交流,博客地址http://www.cnblogs.com/shizhongtao/p/3469776.html 首先,什么是aop,其实通俗一点讲就是,再方法执行时候我们加入其它业务逻辑.比 ...

随机推荐

  1. 移动端H5开发自适应技巧

    移动端H5开发,必要要做到自适应各种分辨率的手机,下面由我为大家大致说一下,需要3步走 第一:head标签中添加: <meta name="viewport" content ...

  2. 01 Mysql数据库初识

    一.数据库概述 1.什么是数据库? 什么是数据库呢? 先来看看百度怎么说的 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增.截取.更新.删除等操作. 所谓“ ...

  3. PHP高级进阶之路

    一:常见模式与框架 学习PHP技术体系,设计模式,流行的框架 常见的设计模式,编码必备 Laravel.ThinkPHP开发必不可少的最新框架 YII.Symfony4.1核心源码剖析 二:微服务架构 ...

  4. AngularJS 在实际应用中优缺点

    AngularJS 在实际应用中优点:模板功能强大丰富,并且是声明式的,自带了丰富的Angular指令:是一个比较完善的前端MV*框架,包含模板,数据双向绑定,路由,模块化,服务,过滤器,依赖注入等所 ...

  5. docker 入门(1)

    1,docker 的安装卸载 https://docs.docker.com/install/linux/docker-ce/ubuntu/ 2,docker中的基本概念 镜像(Image) 容器(C ...

  6. Delphi Label组件

  7. --set-upstream新版本不在支持

    --set-upstream最新版本貌似不在支持,使用--track和--set-uptream-to来替代 --set-upstream: git branch --set-upstream [本地 ...

  8. constant read 和 current read

    来自网络,并且在本机实验完成: onsistent read :我的理解,就是通过scn来读取.  读取的过程中要保证 scn是一致的.举个例子,一个SELECT 语句在SCN=100的时刻开始读取一 ...

  9. 权限和ACL练习题

    1.在/testdir/dir里创建的新文件自动属于g1组,组 g2的成员如:alice能对这些新文件有读写权限,组g3 的成员如:tom只能对新文件有读权限,其它用户(不 属于g1,g2,g3)不能 ...

  10. poj2182 Lost Cows[BIT二分]

    blog题解鸽了许久了..本来说好的切一题写一个题解的说 一个$1 \sim n$数列,已知每个数前面比他小的数个数,试确定该序列. 相当的一道水题.可以发现数列最后一个数是首先可以确定下来的.然后把 ...