刚学spring的时候书上就强调spring的核心就是ioc和aop blablabla......

IOC到处都能看到...AOP么刚开始接触的时候使用在声明式事务上面..当时书上还提到一个用到aop的例子.那就是用aop去简化日志记录.

当初有点疑问,如果这个日志是由aop来记录的,那记录的信息应该是很通用的,不是每个类定制的,那能记录一些什么信息呢?到底能有多详细的日志呢?

于是真正开始做项目的时候关注了一下公司到时是怎么做的.....

利用AOP记录关键方法的入参与返回

spring aop的语法我就不列举了,网上一大堆...公司主要用他记录Controller Facade 与 service等关键方法的入参与返回.

 package com.labofjet.aspect;

 import java.util.UUID;

 import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public abstract class BaseLogAspect { private static final Logger LOGGER = LoggerFactory.getLogger(BaseLogAspect.class); protected Object doLog(ProceedingJoinPoint pjp, String type) throws Throwable {// NOSONAR
UUID uuid = UUID.randomUUID();
String signature = pjp.getSignature().toString();
LOGGER.info("识别号[sequenceid:{}]: 调用{}方法: {}", uuid, type, signature);
LOGGER.debug("识别号[sequenceid:{}]: 参数为 {}", uuid, pjp.getArgs());
try {
long start = System.currentTimeMillis();
Object result = pjp.proceed();
LOGGER.info("识别号[sequenceid:{}]: 调用{}方法: {} 成功! 返回 {}", uuid, type, signature, result);
LOGGER.info("识别号[sequenceid:{}]: 调用消耗时间为[timecost:{}]", uuid, System.currentTimeMillis() - start);
return result;
}
catch (Exception e) {
LOGGER.error("识别号[sequenceid:{}]: 调用{}方法: {} 失败!", uuid, type, signature);
LOGGER.error("识别号[sequenceid:{}]: 异常时输入为 {}", uuid, pjp.getArgs());
LOGGER.error("识别号[sequenceid:{}]: 异常为: ", uuid, e);
throw e;
}
} }

上面这段代码是一个简化版本的日志记录类.利用AOP可以获取到ProceedingJoinPoint,用它可以获取到方法的签名,参数等信息,十分有用.

上面那个BaseLogAspect只是一个基础父类,描述了通用的记录方法...那具体要记录哪些类的方法的信息呢? 这就需要我们去写个子类定义具体的日志记录规则.

 package com.labofjet.blogv3.aspect;

 import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import com.labofjet.aspect.BaseLogAspect; @Aspect
@Component
public class LogAspect extends BaseLogAspect { // private static final Logger LOGGER =
// LoggerFactory.getLogger(LogAspect.class); @Around("within(@org.springframework.stereotype.Controller *)")
public Object logController(ProceedingJoinPoint pjp) throws Throwable {
return doLog(pjp, "Controller");
} // @Around("execution(* gov.gt3.iitms.sbf..*Service.*(..))")
public Object logService(ProceedingJoinPoint pjp) throws Throwable {
return doLog(pjp, "Service");
} // @Around("execution(* gov.gt3.iitms.sbf..*Facade.*(..))")
public Object logFacade(ProceedingJoinPoint pjp) throws Throwable {
return doLog(pjp, "Facade");
} }

这是一种实现,公司记录了controller,facade和service..利用的是around通知..我自己的代码比较简单,不需要这么多,我只需要记录controller的日志就行了,所以我注释掉了另外2个通知.

BaseLogAspect是通用的日志实现,它可以在不同的项目里公用,所以可以放到基础的依赖里去,每个独立的项目依赖这个BaseLogAspect然后实现自己的记录即可.

利用ToStringBuilder来简化参数记录

前面看到日志记录里会把调用方法的入参和结果打印出来...打印一个对象就是调用它的toString方法..如果这个方法不被重写...那么你懂得...完全和没打印差不了多少...

每个DTO,VO等对象都有非常非常多的属性,而且有时候还会不停的增加属性.写toString方法是一件很痛苦的事情(不过eclipse也有快捷键ctrl+alt+s再按s可以生成toString方法).因为要把对象的每个属性拼接起来,很容易错,而且很占用资源(因为String相加了很多次)比较好的做法是使用ToStringBuilder的reflectionToString方法.(ToStringBuilder是org.apache.commons.lang3下的一个类...)

     @Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}

代码非常简短,而且以后修改对象属性也不需要修改toString方法.是不是很简单呢?

==========20170206补==========

eclipse里shift+alt+s然后再按s也可以快速生成toString方法

利用AOP与ToStringBuilder简化日志记录的更多相关文章

  1. Serilog 是 ASP.NET Core 的一个插件,可以简化日志记录

    [翻译] ASP.NET Core 利用 Docker.ElasticSearch.Kibana 来记录日志 原文: Logging with ElasticSearch, Kibana, ASP.N ...

  2. 来一手 AOP 注解方式进行日志记录

    系统日志对于定位/排查问题的重要性不言而喻,相信许多开发和运维都深有体会. 通过日志追踪代码运行状况,模拟系统执行情况,并迅速定位代码/部署环境问题. 系统日志同样也是数据统计/建模的重要依据,通过分 ...

  3. wcf利用IDispatchMessageInspector实现接口监控日志记录和并发限流

    一般对于提供出来的接口,虽然知道在哪些业务场景下才会被调用,但是不知道什么时候被调用.调用的频率.接口性能,当出现问题的时候也不容易重现请求:为了追踪这些内容就需要把每次接口的调用信息给完整的记录下来 ...

  4. 基于AOP和ThreadLocal实现日志记录

    基于AOP和ThreadLocal实现的一个日志记录的例子 主要功能实现 : 在API每次被请求时,可以在整个方法调用链路中记录一条唯一的API请求日志,可以记录请求中绝大部分关键内容.并且可以自定义 ...

  5. springboot整合aop实现网站访问日志记录

    目的: 统一日志输出格式,统计访问网站的ip. 思路: 1.针对不同的调用场景定义不同的注解,目前想的是接口层和服务层. 2.我设想的接口层和服务层的区别在于: (1)接口层可以打印客户端IP,而服务 ...

  6. spring aop通过注解实现日志记录

    首先是几个概念:连接点(Joinpoint).切点(Pointcut).增强(Advice).切面(Aspect) 另外也要使用到注解. 需求:通过注解定义LogEnable.然后程序运行能够识别定义 ...

  7. 使用AOP+Annotation实现操作日志记录

    先创建注解 OperInfo @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @ ...

  8. 利用Spring AOP自定义注解解决日志和签名校验

    转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...

  9. 利用aop插入异常日志的2种方式

    AOP是面向切面编程,利用这个技术可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分的耦合性降低,提高代码的可重用性,同时提高开发效率(来自百度百科). Spring AOP有两种实现方式,一 ...

随机推荐

  1. 我的2013 Q.E.D

    "旧历的年底毕竟最像年底,村镇上不必说,就在天空中也显出将到新年的气象来.灰白色的沉重的晚云中间时时发出闪光,接着一声钝响,是送灶的爆竹:近处燃放的可就更强烈了,震耳的大音还没有息,空气里已 ...

  2. Eclipse调试Android App若选择“Use same device for future launches”就再也无法选择其他设备的问题

    在狂批了某供应商的多媒体控制App有多烂后,夸下海口自己要做一个也是分分钟的事.当然要做好不容易,要超过他们的烂软件还是有信心的.过程中遇到各种坑,其中之一如下 刚开始只使用一个平板进行调试,老是弹出 ...

  3. [OFC]Mellanox发布首个200Gb/s硅光子设备

    [OFC]Mellanox发布首个200Gb/s硅光子设备 讯石光通讯网   发布时间:2016/4/6 8:18:20   编者:iccsz   点击143次     摘要:Mellanox日前在O ...

  4. Linux 文件系统分区基础

    文件系统就是管理设备,组织文件的一些结构和算法. /boot分区,它包含了操作系统的内核和在启动系统过程中所要用到的文件, 建这个分 区是有必要的,因为目前大多数的PC机要受到BIOS的限制,况且如果 ...

  5. BZOJ1500[NOI2005]维修数列

    Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...

  6. 像画笔一样慢慢画出Path的三种方法(补充第四种)

    今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...

  7. 51Nod 1268 和为K的组合

    51Nod  1268  和为K的组合 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使 ...

  8. 以 Console 方式运行、调试、编译 .Net 编写的 Windows 服务

    经常看到一些人在调试 Windows 服务时,很执著的在附加进程后调试!其实 .Net 编写的 Windows 应用程序,包括 Windows 服务都可以编译成 Console 程序!甚至于 ASP. ...

  9. ubuntu中phpmyadmin密码忘记

    在安装mysql时,默认只让你设置了root的密码,如果root的密码忘记,处理办法如下 第一步: 这时你需要进入/etc/mysql目录下,然后sudo vim/vi debian.cnf查看里面的 ...

  10. jq方法中 $(window).load() 与 $(document).ready() 的区别

    通过自学进入了前端的行列,只知道在js中,一开头就写一个: window.onload = function(){ //doing sth} 然后所有的乱七八糟的代码全塞里面,大概知道window.o ...