这是个人在优化项目老代码的一些学习记录,也希望能给各位有需要的大佬提供一种思路,SpringBoot同理
- 首先得导入相关依赖
org.springframework spring-context-support org.springframework spring-context org.springframework spring-core org.springframework spring-beans org.springframework spring-aop org.springframework spring-orm org.springframework spring-context-support org.springframework spring-webmvc
这里我使用的版本是4.2.5.RELEASE的版本
下面开始上代码
2.自定义注解
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoggerOut {
}
@Target({ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogHandler {
}
- 枚举类
public enum LoggerLevel {
INFO,
DEBUG,
WARN,
ERROR
}
- 切面实现
@Aspect
@Component
public class LogAspect {
private final Logger log = LoggerFactory.getLogger(LogAspect.class);
private static final String RETURN_ERROR_PARAM = "数据校验失败";
private static final String RETURN_ERROR_EX = "调用接口失败";
@Autowired
private ParameterUtil parameterUtil;
@Autowired
private IAiLogService aiLogService;
private void commonLogCode(int aiType, String businessType, long startTime, String responseResult, String result, String userName, String businessScenario, String channelSource) {
long endTime = System.currentTimeMillis();
insertAiLog(aiType, businessType, startTime, endTime, responseResult, (null != result && result.length() >= 1800) ? result.substring(0, 1800) : result, userName, businessScenario, channelSource);
}
@Pointcut("execution(@com.axatp.common.annotation.LogHandler * * (..))")
public void resultLog(){
}
@Around(value = "resultLog()")
public Object around(ProceedingJoinPoint point) throws Throwable{
long startTime = 0;
String responseResult= TableStatusEnum.SUCCESS.getStatusName();
MethodSignature signature=(MethodSignature) point.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
LogHandler logHandler = method.getAnnotation(LogHandler.class);
if (logHandler==null){
return point.proceed();
}
//获取请求的类名
String className=point.getTarget().getClass().getName();
Object result=null;
//获取请求的方法名
String methodName = method.getName();
try {
//方法执行前入参打印
before(point,signature,method,className,methodName);
startTime=System.currentTimeMillis();
result=point.proceed();
}catch (BussinessException e){
printLog(LoggerLevel.ERROR,RETURN_ERROR_PARAM,e.getMessage());
responseResult = TableStatusEnum.PARAMETER_ERROR.getStatusName();
}catch (Exception e) {
printLog(LoggerLevel.ERROR,RETURN_ERROR_EX,e.getMessage());
responseResult = TableStatusEnum.FAIL.getStatusName();
} finally {
after(point,signature,method,className,methodName,result,responseResult,startTime);
}
return result;
}
public void before(JoinPoint point, MethodSignature signature, Method method, String className, String methodName) throws BussinessException{
String userName="";
String password="";
String channelSource="";
String businessScenario="";
Object[] args = point.getArgs();
String[] parameterNames = signature.getParameterNames();
Annotation[][] annotationArr = method.getParameterAnnotations();
for (int i = 0; i < parameterNames.length; i++) {
Annotation[] annotations=annotationArr[i];
LoggerOut loggerOut=null;
for (Annotation annotation : annotations) {
if (annotation instanceof LoggerOut){
loggerOut=(LoggerOut) annotation;
break;
}
}
if (loggerOut==null){
//未携带注解的参数不做处理
continue;
}
if ("userName".equals(parameterNames[i])){
userName=(String) args[i];
}else if ("password".equals(parameterNames[i])){
password=(String) args[i];
}else if ("channelSource".equals(parameterNames[i])){
channelSource=(String) args[i];
}else if ("businessScenario".equals(parameterNames[i])){
businessScenario=(String) args[i];
}
Object arg=args[i];
if (arg==null){
printLog(LoggerLevel.INFO,"className:{}===>methodName:{}-param-log====>param:{},value:{}",
className,methodName,parameterNames[i],null);
continue;
}
printLog(LoggerLevel.INFO,"className:{}===>methodName:{}-param-log====>param:{},value:{}",
className,methodName,parameterNames[i],arg);
}
//参数校验
parameterUtil.parameter(channelSource,businessScenario,userName,password);
}
public void after(JoinPoint point,MethodSignature signature, Method method, String className, String methodName,Object result,String responseResult,long startTime){
String userName="";
String channelSource="";
String businessScenario="";
int aiType = 0;
Result results;
Object[] args = point.getArgs();
String[] parameterNames = signature.getParameterNames();
Annotation[][] annotationArr = method.getParameterAnnotations();
for (int i = 0; i < parameterNames.length; i++) {
Annotation[] annotations=annotationArr[i];
LoggerOut loggerOut=null;
for (Annotation annotation : annotations) {
if (annotation instanceof LoggerOut){
loggerOut=(LoggerOut) annotation;
break;
}
}
if (loggerOut==null){
//未携带注解的参数不做处理
continue;
}
//根据参数名称来读取相对应参数值
if (("userName").equals(parameterNames[i])){
userName=(String) args[i];
}else if ("channelSource".equals(parameterNames[i])){
channelSource=(String) args[i];
}else if ("businessScenario".equals(parameterNames[i])){
businessScenario=(String) args[i];
}else if ("aiType".equals(parameterNames[i])){
aiType=(int)args[i];
}
}
//判断执行结果类型
if (result instanceof Result){
results=(Result) result;
commonLogCode(aiType,null,startTime,responseResult,JSON.toJSON(results.getData()).toString(),userName,businessScenario,channelSource);
}else {
if (result==null){
commonLogCode(aiType,null,startTime,responseResult,null,userName,businessScenario,channelSource);
}else {
commonLogCode(aiType,null,startTime,responseResult,result.toString(),userName,businessScenario,channelSource);
}
}
}
public void insertAiLog(int aiType, String businessType, long startTime, long endTime, String responseResult, String responseParam, String operateUser, String businessScenario, String channelSource) {
AiLog aiLog = new AiLog();
aiLog.setPlatformType(String.valueOf(aiType));
aiLog.setBusinessType(businessType);
aiLog.setTimeConsume(String.valueOf(endTime - startTime));
aiLog.setResponseResult(responseResult);
aiLog.setResponseParam(responseParam);
aiLog.setCreatedBy(operateUser);
aiLog.setUpdatedBy(operateUser);
aiLog.setBusinessScenario(businessScenario);
aiLog.setChannelSource(channelSource);
aiLogService.addAiLog(aiLog);
}
public void printLog(LoggerLevel loggerLevel,String formatStr,Object... format){
if (loggerLevel== LoggerLevel.INFO){
log.info(formatStr,format);
}else if (loggerLevel==LoggerLevel.DEBUG){
log.debug(formatStr,format);
}else if (loggerLevel==LoggerLevel.ERROR){
log.error(formatStr,format);
}else if (loggerLevel==LoggerLevel.WARN){
log.warn(formatStr,format);
}
}
}
以上数据校验以及个别常量只是我个人项目所需,大家参考思路即可
使用的话两个注解配合使用即可,LoggerOut标注需要打印以及记录日志的参数
代码还不够完全完善有点冗余,我是想先记录下来,大家有更好的思路欢迎指出~



