Spring AOP实现系统日志功能

最近帮同事实现一个对接口应用添加日志的功能,第一思路就是用SPRING AOP或写个代理类实现

以下用SPring aop实现


<!-- 切面通知实现类 -->
<bean id="aspect" class="com.test.aop.logsystem.aop.LogAspect" />
<aop:config>
<!-- 切入点配置:婚配表达式,可以多个start -->
<aop:pointcut id="pointcut" expression="(execution(* com.test.aop.logsystem.service..*.say*(..)))
|| (execution(* com.test..*.send*(..)))" />
<!-- 切入点配置:婚配表达式,可以多个end -->
<!--切面配置start -->
<aop:aspect ref="aspect">
<aop:before pointcut-ref="pointcut" method="beforeAdvice" />
<aop:after pointcut="execution(* com.test.test..*.*(..))" method="afterFinallyAdvice" />
<aop:after-returning pointcut-ref="pointcut" method="afterReturningAdvice" />
<aop:after-throwing pointcut-ref="pointcut" method="afterThrowingAdvice" />
<aop:around pointcut-ref="pointcut" method="aroundAdvice" />
</aop:aspect>
<!--切面配置end -->
</aop:config>


package com.test.aop.logsystem.aop;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 切面支持类,这里我采用的是 基于Schema的AOP,
* 也可以用注解方式:使用@AspectJ风格的切面声明,
* 但是spring默认不支持注解方式,需要加入<aop:aspectj-autoproxy/>这样Spring就能发现@AspectJ风格的切面并且将切面应用到目标对象
*
* 作用:记录被拦截方法的:1:前置日志,2.后置返回日志 3.执行异常日志,4.环绕通知日志
*
* @author 4*****
*
*/
public class LogAspect {
//前置通知
public void beforeAdvice(JoinPoint joinPoint) {
//记录目标方法执行前的日志
System.out.println("===========before advice");
/*System.out.println("=="+joinPoint.toString());//连接点所在位置的相关信息
System.out.println("=="+joinPoint.toShortString()); //连接点所在位置的简短相关信息
System.out.println("=="+joinPoint.toLongString()); //连接点所在位置的全部相关信息
System.out.println("=="+joinPoint.getThis()); //返回AOP代理对象
System.out.println("=="+joinPoint.getTarget()); //返回目标对象
System.out.println("=="+joinPoint.getArgs()); //返回被通知方法参数列表
System.out.println("=="+joinPoint.getSignature()); //返回当前连接点签名
System.out.println("=="+joinPoint.getSourceLocation());//返回连接点方法所在类文件中的位置
System.out.println("=="+joinPoint.getKind()); //连接点类型
System.out.println("=="+joinPoint.getStaticPart()); //返回连接点静态部分
*/
//判断参数
if(joinPoint.getArgs() == null){//没有参数
return;
}
//获取方法名
String methodName = joinPoint.getSignature().getName();
//获取操作内容(参数类型 + 参数值)
String opContent = optionContent(joinPoint.getArgs(), methodName);
System.out.println(opContent);
/*************记录日志到文件或数据库表,此处省略。。。。 start****************/


/*************记录日志到文件或数据库表,此处省略。。。。 end****************/

}
//后置最终通知
public void afterFinallyAdvice(JoinPoint jp) {

System.out.println("===========after finally advice");
}
//后置返回通知
public void afterReturningAdvice(JoinPoint jp){
//记录目标方法执行完成日志
System.out.println("===========after Returning Advice");
}
//后置异常通知
public void afterThrowingAdvice(JoinPoint jp){
//记录异常日志
System.out.println("===========after Throwing Advice");
}

//环绕通知
//使用proceed()方法来执行目标方法:
public void aroundAdvice(ProceedingJoinPoint jp){
System.out.println("===========around Advice");
try {
Object obj = jp.proceed(); //执行目标方法
} catch (Throwable e) {
e.printStackTrace();
/********回滚,添加报警信息到监控服务器等处理,此处省略。。。。。。。********/

/********回滚,添加报警信息到监控服务器等处理,此处省略。。。。。。。********/
}
}

/**
* 使用Java反射来获取被拦截方法的参数值,
* 将参数值拼接为操作内容
* @param args 参数值
* @param mName 方法名
* @return
*/
public String optionContent(Object[] args, String mName){
if(args == null){
return null;
}
StringBuffer rs = new StringBuffer();
rs.append(mName);
String className = null;
int index = 1;
//遍历参数对象
for(Object info : args){
//获取对象类型
className = info.getClass().getName();
className = className.substring(className.lastIndexOf(".") + 1);
rs.append("[参数"+index+",类型:" + className + ",值:");
//如果是基本数据类型,List,Map则直接获取值
if(info instanceof String
|| info instanceof Integer
|| info instanceof Double
|| info instanceof Float
|| info instanceof BigDecimal
|| info instanceof List
|| info instanceof Map){
rs.append(info);
}else {
//如果是domain对象则获取对象所有特性的get()方法,或者规范domain重写toString(),统一用toString();
Method[] methods = info.getClass().getDeclaredMethods();
// 遍历方法,判断get方法
for(Method method : methods){
String methodName = method.getName();
if(methodName.indexOf("get") == -1){//不是get方法
continue;
}
Object rsValue = null;
try{

rsValue = method.invoke(info);
}catch (Exception e) {
continue;
}
rs.append("(" + methodName+ ":" + rsValue + ")");
}
}
rs.append("]");
index ++;
}
return rs.toString();
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值