引入maven依赖
<!--引用AOP注解功能开始-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--引用AOP注解功能结束-->
自定义注解
/**
* 系统日志记录
*
* @author cjg
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ServiceLog {
/**
*
* @return 监控的业务中心,例如:MRP
*/
String biz() default "MPS";
/**
*
* @return 监控项目,例如:MRP001
*/
String item() default "";
/**
*
* @return 监控的具体业务事务或接口
*/
String trx() default "";
}
自定义切面
import com.cloud.culture.common.annotation.ServiceLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Component
@Aspect
@Slf4j
public class LogAspect {
/**
* * 切入点
*/
@Pointcut("@annotation(com.cloud.culture.common.annotation.ServiceLog) ")
public void entryPoint() {
// 无需内容
}
@Before("entryPoint()")
public void before(JoinPoint joinPoint) {
log.info("=====================开始执行前置通知==================");
try {
//execution(boolean com.cloud.culture.common.service.Impl.TestServiceImp.insert(Map,String))
Signature signature = joinPoint.getSignature();
//获取方法参数
Object[] arguments = joinPoint.getArgs();
//获取目标类
Class<?> aClass = joinPoint.getTarget().getClass();
//获取类名
String targetName = aClass.getName();
//获取当前方法名insert
String methodName = signature.getName();
//获取方法数组
Method[] methods = aClass.getMethods();
String operation = "";
//获取当前方法1
Class<?>[] argTypes = new Class[arguments.length];
for (int i = 0; i < arguments.length; i++) {
argTypes[i] = arguments[i] == null ? null : arguments[i].getClass();
}
Method method;
try {
method = aClass.getMethod(methodName, argTypes);
operation = method.getAnnotation(ServiceLog.class).biz();// 操作人
} catch (NoSuchMethodException e) {
}
//获取当前方法2
MethodSignature signature1 = (MethodSignature)joinPoint.getSignature();
Method method1 = signature1.getMethod();
//获取方法参数类型数组
Class<?>[] parameterTypes = method1.getParameterTypes();
//获取当前方法3
for (Method mm : methods) {
if (mm.getName().equals(methodName)) {
Class<?>[] clazzs = mm.getParameterTypes();
if (clazzs.length == arguments.length) {
//获取代理方法上注解的operation参数的值
operation = mm.getAnnotation(ServiceLog.class).biz();// 操作人
break;
}
}
}
//通过方法获取注解参数值
ServiceLog serviceLog= method.getAnnotation(ServiceLog.class);
String item= serviceLog.item();//""
String biz = serviceLog.biz();//新增用户信息测试操作。。。。。
String trx = serviceLog.trx();//""
StringBuilder paramsBuf = new StringBuilder();
for (Object arg : arguments) {
paramsBuf.append(arg);
paramsBuf.append("&");
}
// *========控制台输出=========*//
log.info("[X用户]执行了[" + operation + "],类:" + targetName + ",方法名:" + methodName + ",参数:"
+ paramsBuf.toString());
log.info("=====================执行前置通知结束==================");
} catch (Throwable e) {
log.info("around " + joinPoint + " with exception : " + e.getMessage());
}
}
@After("entryPoint()")
public void after(JoinPoint joinPoint) {
log.info("=====================开始执行后置通知==================");
try {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class<?> targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String operation = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class<?>[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
operation = method.getAnnotation(ServiceLog.class).biz();// 操作人
break;
}
}
}
StringBuilder paramsBuf = new StringBuilder();
for (Object arg : arguments) {
paramsBuf.append(arg);
paramsBuf.append("&");
}
// *========控制台输出=========*//
log.info("[X用户]执行了[" + operation + "],类:" + targetName + ",方法名:" + methodName + ",参数:"
+ paramsBuf.toString());
log.info("=====================执行后置通知结束==================");
} catch (Throwable e) {
log.info("around " + joinPoint + " with exception : " + e.getMessage());
}
}
/**
* 环绕通知处理处理
*
* @param
* @throws Throwable
*/
@Around("entryPoint()")
public Object around(ProceedingJoinPoint point) throws Throwable {
// 先执行业务,注意:业务这样写业务发生异常不会拦截日志。
Object result = point.proceed();
try {
handleAround(point);// 处理日志
} catch (Exception e) {
log.error("日志记录异常", e);
}
return result;
}
/**
* around日志记录
*
* @param point
* @throws SecurityException
* @throws NoSuchMethodException
*/
public void handleAround(ProceedingJoinPoint point) throws Exception {
Signature sig = point.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Object target = point.getTarget();
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
// 方法名称
String methodName = currentMethod.getName();
// 获取注解对象
ServiceLog aLog = currentMethod.getAnnotation(ServiceLog.class);
// 类名
String className = point.getTarget().getClass().getName();
// 方法的参数
Object[] params = point.getArgs();
StringBuilder paramsBuf = new StringBuilder();
for (Object arg : params) {
paramsBuf.append(arg);
paramsBuf.append("&");
}
// 处理log。。。。
log.info("[X用户]执行了[" + aLog.operation() + "],类:" + className + ",方法名:" + methodName + ",参数:"
+ paramsBuf.toString());
}
@AfterThrowing(pointcut = "entryPoint()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
// 通过request获取登陆用户信息
// HttpServletRequest request = ((ServletRequestAttributes)
// RequestContextHolder.getRequestAttributes()).getRequest();
try {
String targetName = joinPoint.getTarget().getClass().getName();
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class<?> targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String operation = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class<?>[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
operation = method.getAnnotation(ServiceLog.class).biz();
break;
}
}
}
StringBuilder paramsBuf = new StringBuilder();
for (Object arg : arguments) {
paramsBuf.append(arg);
paramsBuf.append("&");
}
log.info("异常方法:" + className + "." + methodName + "();参数:" + paramsBuf.toString() + ",处理了:" + operation);
log.info("异常信息:" + e.getMessage());
} catch (Exception ex) {
log.error("异常信息:{}", ex.getMessage());
}
}
}
service层接口
public interface ILogService {
public boolean insert(Map<String, Object> params, String id);
public boolean update(String name, String id);
public boolean delete(String id);
public boolean doError(String id);
}
实现类
@Service
public class TestServiceImp implements ILogService {
@ServiceLog(biz= "新增用户信息测试操作。。。。。",item= "", trx= "")
@Override
public boolean insert(Map<String, Object> params, String id) {
return false;
}
@ServiceLog(biz= "更新用户信息操作....",item= "", trx= "")
@Override
public boolean update(String name, String id) {
return false;
}
@ServiceLog(biz= "删除操作....",item= "", trx= "")
@Override
public boolean delete(String id) {
return false;
}
@ServiceLog(biz= "异常操作测试....",item= "", trx= "")
@Override
public boolean doError(String id) {
try {
@SuppressWarnings("unused")
int i = 1 / 1;
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
return false;
}
}
测试类
import com.cloud.culture.common.service.ILogService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoSpringbootAopLogApplicationTests {
@Autowired
ILogService logService;
@Test
public void contextLoads() {
Map<String, Object> params = new HashMap<>();
params.put("key1", "v1");
params.put("key2", "v2");
logService.insert(params, "111");
logService.update("king", "kang");
logService.delete("111");
logService.doError("111");
}
}