Spring中AOP注解@Aspect的使用详解

 更新时间:2024年01月18日 08:36:43   作者:可以简单点  
这篇文章主要介绍了Spring中AOP注解@Aspect的使用详解,AOP是种面向切面的编程思想,面向切面编程是将程序抽象成各个切面,将那些影响了多个类的公共行为抽取到一个可重用模块里,减少系统的重复代码,降低模块间的耦合度,增强代码的可操作性和可维护性,需要的朋友可以参考下

AOP思想

AOP(Aspect Oriented Programming)是一种面向切面的编程思想。面向切面编程是将程序抽象成各个切面,即解剖对象的内部,将那些影响了多个类的公共行为抽取到一个可重用模块里,减少系统的重复代码,降低模块间的耦合度,增强代码的可操作性和可维护性。AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理、增强处理。

AOP的使用场景

权限认证、日志、事务处理、增强处理

@Aspect的使用以及基本概念

1.切面类 @Aspect: 定义切面类,加上@Aspect、@Component注解

@Aspect
@Component
//设置注解执行的顺序
@Order(2)
public class AnnotationAspectTest 

2.切点 @Pointcut

/**
 * 定义切点,切点为对应controller
 */
@Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))")
public void aopPointCut(){
}
注:execution表达式第一个*表示匹配任意的方法返回值,第二个*表示所有controller包下的类,第三个*表示所有方法,第一个..表示任意参数个数。

3.Advice,在切入点上执行的增强处理,主要有五个注解:

@Before  在切点方法之前执行

@After  在切点方法之后执行

@AfterReturning 切点方法返回后执行

@AfterThrowing 切点方法抛异常执行

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

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

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

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

具体代码实现

1.AopController,用于校验aop是否生效:
@Controller
@RequestMapping("aop")
public class AopController {
    @RequestMapping("test")
    @ResponseBody
    public String aopTest(User user) {
       // System.out.println(user);
        System.out.println("aop测试");
        return "success";
    }
    @TestAnnotation(flag = false)
    @RequestMapping("aopAnnotationTest")
    @ResponseBody
    public String aopAnnotationTest(User user) {
        // System.out.println(user);
        System.out.println("aopAnnotationTest");
        return "success";
    }
}

2.AspectTest,具体的切面类,用于添加横切逻辑,切点使用execution表达式进行匹配

@Aspect
@Component
//设置注解执行的顺序
@Order(1)
public class AspectTest {
    /**
     * 定义切点,切点为对应controller
     */
    @Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))")
    public void aopPointCut(){
    }
    @Before("aopPointCut()")
    public void testbefor(JoinPoint joinPoint) {
        illegalParam(joinPoint);
        System.out.println("执行方法之前执行。。。。。");
    }
    @After("aopPointCut()")
    public void testAfter(JoinPoint joinPoint) {
        //illegalParam(joinPoint);
        System.out.println("执行方法之后执行。。。。。");
    }
    /**
     *获取请求参数
     * @param joinPoint
     * @return
     */
    private static void  illegalParam(JoinPoint joinPoint) {
        if(joinPoint == null){
            return;
        }
        boolean flag = false;
        try{
            // 参数值
            Object[] args = joinPoint.getArgs();
            if (args != null) {
                for (Object o : args) {
                    System.out.println(o);
                }
            }
        }catch(Exception e){
        }
    }
}

3.AnnotationAspectTest类,具体的切面类,用于添加横切逻辑,切点指定注解

@Aspect
@Component
//设置注解执行的顺序
@Order(2)
public class AnnotationAspectTest {
    /**
     * 定义切点,切点为添加了注解的方法
     */
    @Pointcut("@annotation(com.example.zcs.Aop.annotation.TestAnnotation)")
    public void aopPointCut(){
    }
    @Around("aopPointCut()")
    public Object Around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("AnnotationAspectTest Around start ");
        //获取注解和注解的值
        TestAnnotation annotation = getAnnotation(point);
       if (annotation != null) {
           boolean flag = annotation.flag();
           System.out.println("注解flags的值:" + flag);
       }
        //获取参数
        Object[] args = point.getArgs();
        for (Object arg : args) {
            System.out.println("arg ==>" + arg);
        }
        //去调用被拦截的方法
        Object proceed = point.proceed();
        return proceed;
    }
    //获取注解
    public TestAnnotation getAnnotation(ProceedingJoinPoint point) {
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null){
            return method.getAnnotation(TestAnnotation.class);
        }
        return null;
    }
}

4.注解类TestAnnotation

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestAnnotation {
    boolean flag() default true;
}

到此这篇关于Spring中AOP注解@Aspect的使用详解的文章就介绍到这了,更多相关Spring的@Aspect注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot 中嵌入式 Servlet 容器自动配置原理解析

    Spring Boot 中嵌入式 Servlet 容器自动配置原理解析

    这篇文章主要介绍了Spring Boot 中嵌入式 Servlet 容器自动配置原理解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • maven的settings.xml、pom.xml配置文件使用详解

    maven的settings.xml、pom.xml配置文件使用详解

    本文详解了Maven中的配置文件settings.xml和pom.xml,阐述了它们的作用、配置项以及优先级顺序,settings.xml存在于Maven安装目录和用户目录下,分别作用于全局和当前用户,pom.xml位于项目根路径下
    2024-09-09
  • 关于Controller层和Service层的类报错问题及解决方案

    关于Controller层和Service层的类报错问题及解决方案

    这篇文章主要介绍了关于Controller层和Service层的类报错问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • java 递归深入理解

    java 递归深入理解

    一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,需要的朋友可以参考下
    2012-11-11
  • Java实现跨服务器上传文件功能

    Java实现跨服务器上传文件功能

    这篇文章主要为大家详细介绍了Java实现跨服务器上传文件功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • 一文读懂Jvm类加载机制

    一文读懂Jvm类加载机制

    这篇文章主要介绍了一文读懂Jvm类加载机制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Java矢量队列Vector使用示例

    Java矢量队列Vector使用示例

    Vector类实现了一个动态数组。和ArrayList很相似,但是两者是不同的Vector是同步访问的;Vector包含了许多传统的方法,这些方法不属于集合框架
    2023-01-01
  • Spring Boot Security认证之Redis缓存用户信息详解

    Spring Boot Security认证之Redis缓存用户信息详解

    本文介绍了如何使用Spring Boot Security进行认证,并通过Redis缓存用户信息以提高系统性能,通过配置RedisUserDetailsManager,我们成功地将用户信息存储到了Redis中,并在Spring Security中进行了集成,需要的朋友可以参考下
    2024-01-01
  • Java使用itext5实现PDF表格文档导出

    Java使用itext5实现PDF表格文档导出

    这篇文章主要介绍了Java使用itext5实现PDF表格文档导出,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • 解决Spring Mvc中对象绑定参数重名的问题

    解决Spring Mvc中对象绑定参数重名的问题

    最近在工作中遇到了参数绑定的一个问题,发现网上这方面的资料较少,索性自己来总结下,下面这篇文章主要给大家介绍了关于如何解决Spring Mvc中对象绑定参数重名问题的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-08-08

最新评论