SpringBoot项目切面编程之@Aspect

SpringBoot项目切面编程之@Aspect,第1张

SpringBoot项目切面编程之@Aspect

场景:
aop切面编程想必大家都不陌生了,aspect可以很方便开发人员对请求指定拦截层,一般是根据条件切入到controller控制层,做一些鉴权、分析注解、获取类名方法名参数、记录 *** 作日志等

引入 aop 依赖包:


    org.springframework.boot
    spring-boot-starter-aop

切入流程:
1、创建组件类并标记注解@Aspect
2、定义切入点标记注解@Pointcut
3、使用切入点切入标记注解@Before或者@After

代码案例:

package com.hkl.modules.aspect;

import com.hkl.annotation.FieldConvert;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;


@Component
@Aspect
@Slf4j
public class AopConfigure {


    
    @Pointcut("execution( * com.hkl.modules.controller..*(..))")
    public void getMethods() {

    }
    
    @Pointcut("@annotation(com.hkl.annotation.FieldConvert)")
    public void withAnnotationMethods() {
    }


    
    @Before(value = "getMethods() && withAnnotationMethods()")
    public void doBefore(JoinPoint joinPoint){
        //获取Servlet容器
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取request请求
        HttpServletRequest request = attributes.getRequest();
        //执行方法对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        //判断切入的方法是否标记xxx注解
        //boolean flag = method.isAnnotationPresent(xxx.class);
        //CollUtil.toList(role).contains(userType);

        
        //1、鉴权、解析request请求对象中设置的属性
        //2、反射解析注解、记录 *** 作日志等
        

        log.info("测试切入{}成功,方法名:"+method.getName(), "@Before");
    }


    
    @After(value = "getMethods() && withAnnotationMethods()")
    public void doAfter(JoinPoint joinPoint) {
        //业务 *** 作同 @Before 方式

        MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        log.info("测试切入{}成功,是否包含注解:"+method.isAnnotationPresent(FieldConvert.class), "@After");
        log.info("注解中的属性值:"+method.getAnnotation(FieldConvert.class).codeType());
    }


}

测试代码:

@FieldConvert(codeType = "aa")
@ApiOperation(value = "测试切面用")
@GetMapping(value = "/getTestAop")
CommonResult getTestAop(){
    return success("响应成功!");
}

测试结果成功切入: 

总结和注意:
1、定义切入点,支持指定包按路径切入,也支持指定是否标记某个注解切入
2、aop默认无法切入 private 修饰的方法,切入点表达式定义的修饰符要和被切入的方法修饰符一致,否则无法切入
3、如下切入点规则,可以切入 public 修饰或者省略修饰符的方法,推荐此方式

@Pointcut("execution( * com.hkl.modules.controller..*(..))")

4、如果配置成 @Pointcut("execution(public * com.hkl.modules.controller..*(..))") 只能切入 public 修饰的方法

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/zaji/5611733.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-15
下一篇2022-12-15

发表评论

登录后才能评论

评论列表(0条)

    保存