一文带你了解sprinboot AOP和简单使用

举报
神的孩子在歌唱 发表于 2024/04/16 09:31:04 2024/04/16
【摘要】 前言这是我在这个网站整理的笔记,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱Spring Boot AOP什么是AOP?AOP(面向切面编程)是一种编程范式,它允许我们在程序运行时通过将横切关注点(如日志记录、事务管理等)从核心业务逻辑中分离出来,以提高代码的可重用性和可维护性。Spring Boot AOP的优势Spring Boot提供了强大的AOP支持,使得我们可以更轻松地实现...

前言

这是我在这个网站整理的笔记,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱

Spring Boot AOP

什么是AOP?

AOP(面向切面编程)是一种编程范式,它允许我们在程序运行时通过将横切关注点(如日志记录、事务管理等)从核心业务逻辑中分离出来,以提高代码的可重用性和可维护性。

Spring Boot AOP的优势

Spring Boot提供了强大的AOP支持,使得我们可以更轻松地实现横切关注点的功能。以下是Spring Boot AOP的一些优势:

  1. 模块化开发:AOP让我们能够将横切关注点与核心业务逻辑分离,从而使代码更易于理解和维护。

  2. 代码重用:通过将通用的横切关注点封装成切面,我们可以在多个模块或项目中重复使用,避免重复编写相同的代码。

  3. 运行时动态代理:Spring Boot AOP使用动态代理技术,在程序运行时动态地将切面织入到目标对象中,而无需修改目标对象的源代码。

Spring Boot AOP的使用步骤

以下是使用Spring Boot AOP的一般步骤:

  1. 定义切面类:创建一个切面类,该类包含了我们想要在目标方法执行前、执行后或出现异常时执行的逻辑。

  2. 定义切点:定义一个切点,它表示我们希望在哪些方法上应用切面逻辑。

  3. 配置AOP:在配置类中配置AOP,指定要扫描的包和切面类。

  4. 测试:编写测试代码,验证AOP是否按预期工作。

AOP相关名词解释

在理解Spring Boot AOP的过程中,以下是一些常见的名词和概念:

  1. 切面(Aspect):切面是横切关注点的具体实现。它包含了在目标方法执行前、执行后或出现异常时要执行的逻辑。切面可以被应用于一个或多个切点。

  2. 切点(Pointcut):切点是在应用程序中选择连接点的表达式。连接点是在应用程序中可以插入切面的特定位置,如方法执行前、执行后或出现异常时等。切点使用表达式语言来定义要拦截的方法。

  3. 连接点(Join Point):连接点是在应用程序执行期间可以插入切面的特定位置。它可以是方法调用、方法执行、异常抛出等。

  4. 通知(Advice):通知是切面在连接点上执行的具体操作。Spring提供了以下几种通知类型:前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、异常通知(AfterThrowing)和环绕通知(Around)。

  5. 织入(Weaving):织入是将切面应用到目标对象中的过程。Spring AOP使用动态代理或字节码增强来实现织入。

  6. 目标对象(Target Object):目标对象是应用程序中被代理的对象,它包含了核心业务逻辑。

  7. 代理(Proxy):代理是一个包装了目标对象的对象,它拦截对目标对象的方法调用,并在必要时调用切面逻辑。

以上是一些常见的AOP相关名词,理解这些名词将有助于更好地理解和应用Spring Boot AOP。

springboot实现AOP

在Spring Boot中,可以使用@Aspect注解实现AOP(面向切面编程)。以下是几种常见的方式:

  1. 测试条件

    在service层定义一个HelloWord对象:

    @Service
    public class HelloWord {
        public String helloWord() {
            return "你好";
        }
    }

    编写测试类

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = ChenApplication.class)
    public class TestMethod {
    ​
        @Autowired
        private HelloWord helloWords;
    ​
        @Test
        public void helloTest() {
    ​
            System.out.println(helloWords.helloWord());
        }
    }
    ​


  2. 基于方法:使用@Before@After@AfterReturning@AfterThrowing@Around等注解来定义通知(Advice)方法,这些方法将在目标方法执行前、执行后、返回结果后或抛出异常时执行。

    例如:

    @Aspect
    @Component
    public class BeforeAspect {
        @Before("execution(* com.chen.service.HelloWord.*(..))")
        public void beforeAdvice(JoinPoint joinPoint) {
            // 在目标方法执行前执行的逻辑
            System.out.println("执行方法前的操作");
        }
    }


    image-20231020171127002


  3. 基于注解:使用@Pointcut和自定义注解来定义切点(Pointcut),并通过@Around注解的通知方法来拦截带有特定注解的方法。

    例如:

    定义注解

    @Target({ ElementType.PARAMETER, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Hello {
    ​
        public String name() default "";
    }

    定义AOP


    @Aspect
    @Component
    public class AroundHello {
    ​
    ​
    //    定义切点: 基于注解
        @Pointcut("@annotation(com.chen.common.config.aspectj.annotation.Hello)")
        public void aroundHello() {}
    ​
    //    环绕通知
        @Around("aroundHello()")
        public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            // 在目标方法执行前执行的逻辑
            System.out.println("执行前");
            // 在目标方法返回结果后执行的逻辑
            Object result = proceedingJoinPoint.proceed();
            Hello annotationHello = getAnnotationHello(proceedingJoinPoint);
            if (annotationHello != null) {
                System.out.println("执行后" + annotationHello.name() + "," + result);
            }
            return result;
    ​
        }
    ​
        /**
         * 是否存在注解,如果存在就获取
         */
        private Hello getAnnotationHello(JoinPoint joinPoint) throws Exception {
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature)signature;
            Method method = methodSignature.getMethod();
    ​
            if (method != null) {
                return method.getAnnotation(Hello.class);
            }
            return null;
        }
    }


    测试结果


    image-20231020180258284

  4. 基于类或接口:使用@Pointcut注解和类或接口的匹配表达式来定义切点,然后通过其他通知注解来定义通知方法。

    例如:

    @Service
    public class HelloWord {
        public String helloWord() {
            System.out.println("你好呀");
            return "你好";
        }
    }



    @Aspect
    @Component
    public class AfterAspect {
        @Pointcut("within(com.chen.service.*)")
        public void serviceMethods() {}
    ​
        @After("serviceMethods()")
        public void afterAdvice(JoinPoint joinPoint) {
            // 在目标类中的方法执行后执行的逻辑
            System.out.println("方法执行后");
        }
    }
    ​

这些是一些常见的使用@Aspect注解实现AOP的方式。通过定义切点和通知方法,可以在适当的时机拦截和处理目标方法的调用。具体选择哪种方式取决于你的需求和场景。

测试结果

image-20231023113601976


作者:神的孩子都在歌唱

本人博客:https://blog.csdn.net/weixin_46654114

转载说明:务必注明来源,附带本人博客连接。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。