自定义注解实现日志记录
创建spring 项目
创建日志注解@Log
package com.serendipity.annotation.annotation;
import java.lang.annotation.*;
/**
* @Describe : 日志注解
* @Author : Serendipity
* @Create : 2020/6/21 21:27
*/
@Documented //生成文档
@Retention(RetentionPolicy.RUNTIME)// 注解保留周期
@Target(ElementType.METHOD) //注解作用范围,类上/方法上/字段上/包上
public @interface Log {
/* 默认的value方法使用时可不用写key */
String value() default "";
}
使注解生效,使用spring aop,创建LogAspect对象
package com.serendipity.annotation.aspect;
import com.serendipity.annotation.annotation.Log;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @ClassName LogAspect
* @Description aop使注解生效
* @Author Serendipity
* @Date 2020/6/21
* @Version 1.0
**/
@Aspect
@Component
@Slf4j
public class LogAspect {
/**
* 配置切入点
*/
@Pointcut("@annotation(com.serendipity.annotation.annotation.Log)")
public void logPointcut() {}
/**
* 配置后置通知,使用在方法logPointcut()上注册的切入点
* @param joinPoint join point for advice
*/
@AfterReturning("logPointcut()")
public void logAfter(JoinPoint joinPoint){
/* 获取方法签名 */
MethodSignature sign = (MethodSignature) joinPoint.getSignature();
Method method = sign.getMethod();
/* 获得方法上自定义注解对象 */
Log annotation = method.getAnnotation(Log.class);
String value = annotation.value();
Object arg = joinPoint.getArgs()[0];
/* 以下应为正式的日志记录,记录数据库等 */
log.info("日志记录:【"+value+"】"+":年龄为"+arg);
}
/**
* 配置异常通知,异常记录日志
* @param joinPoint join point for advice
*/
@AfterThrowing(value = "logPointcut()",throwing = "ex")
public void logException(JoinPoint joinPoint,Exception ex){
/* 获取方法签名 */
MethodSignature sign = (MethodSignature) joinPoint.getSignature();
Method method = sign.getMethod();
/* 获得方法上自定义注解对象 */
Log annotation = method.getAnnotation(Log.class);
String value = annotation.value();
Object arg = joinPoint.getArgs()[0];
/* 以下应为正式的日志记录,记录数据库等 */
log.info("异常日志记录:【"+value+"】"+":年龄为"+arg+".异常信息:"+ex.getMessage());
}
}
创建业务测试类TestService
package com.serendipity.annotation.service;
import com.serendipity.annotation.annotation.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @ClassName TestService
* @Description 业务类对象(测试)
* @Author Serendipity
* @Date 2020/6/21
* @Version 1.0
**/
@Component
@Slf4j
public class TestService {
@Log("用户日志:新增")
public void addTest(Integer age){
/* 业务代码 */
log.info("年龄为-->"+age);
/* 异常测试 */
int r = 1/0;
}
}
启动spring 测试
package com.serendipity.annotation;
import com.serendipity.annotation.service.TestService;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AnnotationApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.scan("com.serendipity.annotation");
applicationContext.register(AnnotationAwareAspectJAutoProxyCreator.class);//开启对aop的支持
applicationContext.refresh();//刷新容器
TestService bean = applicationContext.getBean(TestService.class);
bean.addTest(18);//调用目标方法
}
}
运行,异常代码注释掉,效果如下
运行,异常代码开启,异常通知也成功切入,简单的aop+自定义注解实现日志记录已实现