spring aop通过注解实现日志记录
本文内容纲要:spring aop通过注解实现日志记录
首先是几个概念:连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、切面(Aspect)
另外也要使用到注解。
需求:通过注解定义LogEnable。然后程序运行能够识别定义了LogEnable注解的方法记录日志。
1.定义注解
package cn.duanjt.util;import java.lang.annotation.*;
/**
* 记录日志的注解类
* @author 段江涛
* @date 2018-11-08
*/
@Target(ElementType.METHOD)//表示用于标识方法
@Retention(RetentionPolicy.RUNTIME)//表示运行时保留
public @interface LogEnable {
/**
* 主要是标志日志的描述信息
* @return
*/
String note() default "";
}
2.定义需要监听的类和方法
package cn.duanjt.service;import org.springframework.stereotype.Service;
import cn.duanjt.Pojo.Student;
import cn.duanjt.util.LogEnable;
@Service
public class StudentService {
//定义注解,然后描述当前方法的作用
@LogEnable(note="获取学生信息")
public Student getStudent(int id) {
if (id == 0) {
throw new RuntimeException("编码不能为0");
}
Student stu = new Student();
stu.setId(id);
stu.setName("zhangsan");
stu.setAddr("重庆");
return stu;
}
//未定义注解,将不会被监听
public int getId(int id) {
return id + 1;
}
}
3.定义切面,记录日志
package cn.duanjt.util;import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogHelper {
// 没有单独定义切点,直接在环绕方法里面处理[包cn.duanjt.service下面的所有类下面的所有方法,同时包含LogEnable注解的将被监听]
@Around("execution(* cn.duanjt.service.*.*(..)) && @annotation(LogEnable)")
public Object around(ProceedingJoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
long time = System.currentTimeMillis(); //记录开始时间
String className = point.getTarget().getClass().getName(); // 类名
String method = className + "." + signature.getName(); //方法名
Object[] args = point.getArgs(); // 参数
LogEnable logEnable= signature.getMethod().getAnnotation(LogEnable.class);
String logNote=logEnable.note(); //日志信息
try {
Object result = point.proceed();
System.out.println("方法名:" + method);
System.out.println("参数:" + StringUtils.join(args));
System.out.println("返回值:" + result.toString());
System.out.println("日志功能:" + logNote);
System.out.println("耗时:" + (System.currentTimeMillis() - time) + "毫秒");
System.out.println("-----------------------");
return result;
} catch (Exception e) {
System.out.println("方法名1:" + method);
System.out.println("参数:" + StringUtils.join(args));
System.out.println("日志功能:" + logNote);
System.out.println("异常信息:" + e.getMessage());
System.out.println("耗时:" + (System.currentTimeMillis() - time) + "毫秒");
System.out.println("-----------------------");
return null;
} catch (Throwable e) {
return null;
}
}
}
4.在主程序上要加上注解@EnableAspectJAutoProxy。我这里使用的是springboot,如下:
package cn.duanjt;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@ComponentScan("cn.duanjt")
@EnableAspectJAutoProxy //表示启用AOP
public class ServerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ServerDemoApplication.class, args);
}
}
最后,运行结果如下:
方法名:cn.duanjt.service.StudentService.getStudent参数:1
返回值:Student [id=1, name=zhangsan, addr=重庆]
日志功能:获取学生信息
耗时:0毫秒
-----------------------
注意:
@EnableAspectJAutoProxy用于开启全局的AOP
LogHelper类上面的@Aspect和*@Component是必须的,前者用于标注是切面,后者用于将对象注入到spring容器*
*3. 切面表达式@Around("execution(* cn.duanjt.service.*.*(..)) && @annotation(LogEnable)").*一定需要execution。详细的可以下去再了解
本文内容总结:spring aop通过注解实现日志记录
原文链接:https://www.cnblogs.com/duanjt/p/9927981.html
以上是 spring aop通过注解实现日志记录 的全部内容, 来源链接: utcz.com/z/296929.html