Spring注解 AOP@Aspect的详细介绍

前言:在spring AOP中业务逻辑仅仅只关注业务本身,将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

相关注解介绍:

@Aspect:作用是把当前类标识为一个切面供容器读取
 
@PointcutPointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 publicvoid型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。
@Around:环绕增强,相当于MethodInterceptor
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After: final增强,不管是抛出异常或者正常退出都会执行

一、基本概念:
1、切面类 @Aspect: 定义切面类,加上@Aspect、@Component注解;//下文有展示
2、切点 @Pointcut:
// 指定切面方法
@Pointcut(“execution(public * com.rest.module….(…))”)
public void getMethods() {
}
注:execution表达式第一个表示匹配任意的方法返回值,…(两个点)表示零个或多个,第一个…表示module包及其子包,第二个表示所有类, 第三个*表示所有方法,第二个…表示方法的任意参数个数
// 指定注解
@Pointcut("@annotation(com.rest.utils.SysPlatLog)")
public void withAnnotationMethods() {
}
注:在这里,自定义了一个注解类,方法加注解即可使用;
/**

  • 系统平台日志记录
    */
    public @interface SysPlatLog {
    // 操作名称
    String operateName() default “”;
    // 操作描述
    String logNote() default “”;
    }
    3、Advice,在切入点上执行的增强处理,主要有五个注解:

@Before 在切点方法之前执行

   @After  在切点方法之后执行

   @AfterReturning 切点方法返回后执行

@AfterThrowing 切点方法抛异常执行

@Around 属于环绕增强,能控制切点执行前,执行后

4、JoinPoint :方法中的参数JoinPoint为连接点对象,它可以获取当前切入的方法的参数、代理类等信息,因此可以记录一些信息,验证一些信息等;

5、使用&&、||、!、三种运算符来组合切点表达式,表示与或非的关系;

6、@annotation(annotationType) 匹配指定注解为切入点的方法;

7、//aop代理对象
Object aThis = joinPoint.getThis();
//被代理对象
Object target = joinPoint.getTarget();

8、调用切面注解:

@SysPlatLog(operateName = “查看详情”,logNote = “查看详情”)
@SneakyThrows
public Result getItem(@RequestParam(required = false) String bs){
}

二、代码展示:

import com.npc.rest.common.properites.AppSupPlatProperties;
import com.sys.model.SysLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.*;

@Aspect
@Slf4j
@Component
public class SysPlatLogAspect {

    /**
     * 指定切面
     */
    @Pointcut("execution(public * com.rest.module..*.*(..))")
    public void getMethods() {
   }
    /**
     * 指定注解
     */
    @Pointcut("@annotation(com.rest.utils.SysPlatLog)")
    public void withAnnotationMethods() {
    }

    /***
     * 拦截控制层的操作日志
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @After(value = "getMethods() && withAnnotationMethods()")
    public void recordLog(JoinPoint joinPoint) throws Throwable {
        SysLog sysLog = new SysLog();
        SysPlatLog sysPlatLog = getInter(joinPoint);
        sysLog.setOperateName(sysPlatLog.operateName());
        sysLog.setLogNote(sysPlatLog.logNote());
        sysLog.setLogTime(new Date());
        sysLog.setAppCode(AppSupPlatProperties.getAppCode());
    }

    public SysPlatLog getInter(JoinPoint joinPoint) throws ClassNotFoundException {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                    SysPlatLog sysPlatLog = method.getAnnotation(SysPlatLog.class);
                    return sysPlatLog;
                }
            }
        }
        return null;
    }
}

参考文献:
https://blog.csdn.net/fz13768884254/article/details/83538709

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值