springboot實現(xiàn)基于aop的切面日志
本文實例為大家分享了springboot實現(xiàn)基于aop的切面日志的具體代碼,供大家參考,具體內(nèi)容如下
通過aop的切面方式實現(xiàn)日志
通切面攔截所有指定包下的所有方法
@Aspect
@Component
@EnableAspectJAutoProxy
public class LogAspect1{
? ? Logger logger = LoggerFactory.getLogger(LogAspect.class);
? ??
/**
?* 攔截切點
?*/
? ? @Pointcut("execution(*xx.xx.controller.*.*(..))")
? ? private void logPointCut() {
? ? ? ? logger.info("進入注解攔截");
? ? }
? ? //前置通知,在方法之前通知
? ? @Before(value = "logPointCut()")
? ? public void before(JoinPoint jp) {
? ? ? ? logger.info("方法調(diào)用前:" + "類名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName());
? ? }
? ? //后置通知
? ? @After(value = "logPointCut()")
? ? public void doAfter(JoinPoint jp) {
? ? ? ? logger.info("方法調(diào)用結(jié)束:" + "類名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName());
? ? }
? ? //環(huán)繞通知
? ? @Around("logPointCut()")
? ? public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
? ? ? ? logger.info("方法開始調(diào)用》》》》》》");
? ? ? ? Object retVal = pjp.proceed();
? ? ? ? logger.info("方法調(diào)用結(jié)束》》》》》》");
? ? ? ? return retVal;
? ? }
? ? //返回通知
? ? @AfterReturning(pointcut = "logPointCut()")
? ? public void doAfterReturning(JoinPoint jp) {
? ? ? ? logger.info("寫入日志");
? ? }
? ? //異常通知
? ? @AfterThrowing(pointcut = "logPointCut()", throwing = "ex")
? ? public void doAfterThrowing(JoinPoint jp, Throwable ex) {
? ? ? ? logger.info("方法異常,異常信息:" + ex.getMessage());
? ? }
}攔截自定義注解
定義一個日志注解,在所有要需要記錄的方法上加蓋注解即可被后續(xù)的aop攔截處理
代碼如下
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
? ? /**
? ? ?* 日志主題
? ? ?*/
? ? public String title() default "";
? ? /**
? ? ?* 操作具體業(yè)務
? ? ?*/
? ? public String business() default "";
? ? /**
? ? ?* 是否保留請求參數(shù)
? ? ?*/
? ? public boolean isSaveRequestData() default false;
? ? /**
? ? * 日志的類別,主要用于日志的分開記錄和查詢
? ? **/
LogType logType() default LogType.LOGIN;
}攔截切面的實現(xiàn)
@Aspect
@Component
@EnableAspectJAutoProxy
public class LogAspect {
? ? Logger logger = LoggerFactory.getLogger(LogAspect.class);
? ? @Autowired
? ? private ServiceDemo serviceDemo;
? ? /**
? ? ?* 攔截切點
? ? ?*/
? ? @Pointcut("@annotation(moling.evolution.demo.aop.annotation.Log)")
? ? private void logPointCut() {
? ? ??
? ? }
? ? //前置通知,在方法之前通知
? ? @Before(value = "logPointCut()")
? ? public void before(JoinPoint jp) {
? ? ? ? logger.info("方法調(diào)用前:" + "類名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName());
? ? }
? ? //后置通知
? ? @After(value = "logPointCut()")
? ? public void doAfter(JoinPoint jp) {
? ? ? ? logger.info("方法參數(shù):{}", jp.getArgs());
? ? ? ? logger.info(" ?{} || {}", jp.getStaticPart().getId(), jp.getStaticPart().getSourceLocation());
? ? ? ? jp.getStaticPart().getId();
? ? ? ? logger.info("方法調(diào)用結(jié)束:" + "類名:" + jp.getTarget().getClass().getName() + "方法名 :" + jp.getSignature().getName());
? ? }
? ? //環(huán)繞通知
? ? @Around("logPointCut()")
? ? public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
? ? ? ? logger.info("方法開始調(diào)用》》》》》》");
? ? ? ? Object retVal = pjp.proceed();
? ? ? ? logger.info("方法調(diào)用結(jié)束》》》》》》");
? ? ? ? return retVal;
? ? }
? ? //返回通知
? ? @AfterReturning(pointcut = "logPointCut()", returning = "object")
? ? public void doAfterReturning(JoinPoint jp, Object object) {
? ? ? ? System.out.println("返回通知");
? ? ? ? Log log = null;
? ? ? ? try {
? ? ? ? ? ? log = getAnnotationLog(jp);
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? System.out.println(object);
? ? ? ? System.out.println(log);
? ? ? ? if (log != null) {
? ? ? ? ? ? logger.info(log.title());
? ? ? ? ? ? logger.info(log.business());
? ? ? ? ? ? logger.info(log.user());
? ? ? ? ? ? logger.info(log.isSaveRequestData() + "");
? ? ? ? } else {
? ? ? ? ? ? logger.error("獲取注解信息失敗");
? ? ? ? }
? ? ? ? serviceDemo.demo();
? ? }
? ? //異常通知
? ? @AfterThrowing(pointcut = "logPointCut()", throwing = "ex")
? ? public void doAfterThrowing(JoinPoint jp, Throwable ex) {
? ? ? ? logger.info("方法異常,異常信息:" + ex.getMessage());
? ? ? ? serviceDemo.error();
? ? }
? ? /**
? ? ?* 是否存在注解,如果存在就獲取
? ? ?*/
? ? private Log getAnnotationLog(JoinPoint joinPoint) throws Exception {
? ? ? ? Signature signature = joinPoint.getSignature();
? ? ? ? MethodSignature methodSignature = (MethodSignature) signature;
? ? ? ? Method method = methodSignature.getMethod();
? ? ? ? if (method != null) {
? ? ? ? ? ? return method.getAnnotation(Log.class);
? ? ? ? }
? ? ? ? return null;
? ? }
}基于事件通知實現(xiàn)日志的記錄
- 攔截切面的實現(xiàn)
@Aspect
@Component
@EnableAspectJAutoProxy
public class LogAspectContext {
? ? Logger logger = LoggerFactory.getLogger(LogAspectContext.class);
? ? @Autowired
? ? private ApplicationContext applicationContext;
? ? /**
? ? ?* 攔截切點
? ? ?*/
? ? @Pointcut("@annotation(moling.evolution.demo.aop.annotation.Log)")
? ? private void logPointCut() {
? ? ? ? logger.info("進入注解攔截");
? ? }
? ? //返回通知
? ? @AfterReturning(pointcut = "logPointCut()", returning = "object")
? ? public void doAfterReturning(JoinPoint jp, Object object) throws Exception {
? ? ? ? applicationContext.publishEvent(new LogSuccessEvent(jp, null));
? ? }
? ? //異常通知
? ? @AfterThrowing(pointcut = "logPointCut()", throwing = "ex")
? ? public void doAfterThrowing(JoinPoint jp, Throwable ex) {
? ? ? ? logger.info("方法異常,異常信息:" + ex.getMessage());
? ? ? ? applicationContext.publishEvent(new LogSuccessEvent(jp, ex));
? ? }
? ? /**
? ? ?* 是否存在注解,如果存在就獲取
? ? ?*/
? ? private Log getAnnotationLog(JoinPoint joinPoint) throws Exception {
? ? ? ? Signature signature = joinPoint.getSignature();
? ? ? ? MethodSignature methodSignature = (MethodSignature) signature;
? ? ? ? Method method = methodSignature.getMethod();
? ? ? ? if (method != null) {
? ? ? ? ? ? return method.getAnnotation(Log.class);
? ? ? ? }
? ? ? ? return null;
? ? }
}@Slf4j
@Service
public class ApplicationListener implements org.springframework.context.ApplicationListener<LogSuccessEvent> {
? ? @Autowired
? ? private ServiceDemo demo;
? ? @Override
? ? public void onApplicationEvent(LogSuccessEvent event) {
? ? ? ? JoinPoint joinPoint = event.getJp();
? ? ? ? Throwable ex = event.getThrowable();
? ? ? ? if (ex == null) {
? ? ? ? ? ? demo.demo();
? ? ? ? } else {
? ? ? ? ? ? demo.error();
? ? ? ? }
? ? }
}@Slf4j
public class LogSuccessEvent extends ApplicationEvent {
? ? /**
? ? ?* Create a new ApplicationEvent.
? ? ?*
? ? ?* @param source the component that published the event (never {@code null})
? ? ?*/
? ? private JoinPoint jp;
? ? private Throwable throwable;
? ? public LogSuccessEvent(Object source, Throwable throwable) {
? ? ? ? super(source);
? ? ? ? this.throwable = throwable;
? ? ? ? this.jp = (JoinPoint) source;
// ? ? ? ?Log logger = (Log) source;
// ? ? ? ?log.info(logger.title());
// ? ? ? ?log.info(logger.business());
// ? ? ? ?log.info(logger.user());
// ? ? ? log.info(logger.isSaveRequestData() + "");
? ? }
? ? public JoinPoint getJp() {
? ? ? ? return jp;
? ? }
? ? public Throwable getThrowable() {
? ? ? ? return throwable;
? ? }
}以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
MyBatis中RowBounds實現(xiàn)內(nèi)存分頁
RowBounds是MyBatis提供的一種內(nèi)存分頁方式,適用于小數(shù)據(jù)量的分頁場景,本文就來詳細的介紹一下,具有一定的參考價值,感興趣的可以了解一下2024-12-12
java基礎(chǔ)--自己動手實現(xiàn)一個LRU
這篇文章主要介紹了運用方案如何實現(xiàn)LUR,文章中通過代碼講解的非常詳細,對大家的工作或?qū)W習有一定的參考價值,感興趣的朋友可以參考一下2021-08-08
在SpringBoot中使用YourKit進行性能調(diào)優(yōu)的教程詳解
在應用程序的開發(fā)過程中,性能調(diào)優(yōu)是一個重要的環(huán)節(jié),在SpringBoot應用程序中,我們可以使用YourKit來進行性能調(diào)優(yōu),YourKit是一款非常強大的Java性能調(diào)優(yōu)工具,在本文中,我們將介紹如何在 SpringBoot應用程序中使用YourKit進行性能調(diào)優(yōu)2023-06-06
HarmonyOS實現(xiàn)Java端類似Nine-Patch氣泡聊天框代碼
在HarmonyOS Java端實現(xiàn)氣泡聊天框,與Android 上的9圖(Nine-Patch)有相似的實現(xiàn)方式,在HarmonyOS中,可以使用ShapeElement和ElementContainer來創(chuàng)建和管理可伸縮的氣泡背景,下面提供一個簡單的示例代碼,可以在 HarmonyOS 中實現(xiàn)類似于Android的Nine-Patch氣泡聊天框效果2024-07-07

