Spring5应用之AOP注解编程

作者简介 :☕️大家好,我是Aomsir,一个爱折腾的开发者!
个人主页Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏
当前专栏Spring5应用专栏_Aomsir的博客

前言

在之前关于AOP的探讨中,我们主要依赖于Spring的XML配置来定义切入点、组装等关键组件。然而,随着开发趋势的演进,现代的应用更多地是基于SpringBoot构建的,并且对于AOP部分,注解方式已经成为了首选。在本篇中,我将引导大家探索如何仅通过注解轻松实现AOP编程

开发步骤

在AOP的进阶路径上,虽然我们转向了注解驱动的编程方式,但其核心概念和实践流程并未发生根本的改变。注解仅仅是将我们原先在XML中的配置以更为简洁、直观的方式呈现出来,让我们的代码更为集中和整洁。在这种新的方式下,AOP的四步编程方法仍然适用:

  1. 创建原始类对象
  2. 设计切面类 。在这个类中,我们需要:
    • 定义切入点:明确指出哪些方法需要被增强
    • 描述额外功能:这是我们想要加入到原始方法中的新功能
    • 实施组装 :确保原始方法和额外功能在正确的时机、正确的顺序下被执行 简言之,尽管我们采用了新的注解方式,但AOP的本质和核心流程都保持不变
java 复制代码
/**
 * 切面类:标注有@Aspect注解,表示一个切面
 */
@Aspect
public class MyAspect {
    private static final Logger log = LoggerFactory.getLogger(MyAspect.class);

    /**
     * 环绕通知(额外功能):是Spring AOP中最强大的通知类型,能够全面地控制连接点。甚至可以控制是否执行连接点
     * 类似于MethodInterceptor中的invoke方法
     * 注解参数中书写切入点表达式
     * @param joinPoint 连接点:类似于Method,args的封装
     * @return 原始方法的返回值
     */
    @Around("execution(* login(..))")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        log.debug("log before");

        // 执行原始方法
        Object ret = joinPoint.proceed();

        log.debug("log after");
        return ret;
    }
}
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="userService" class="com.aomsir.basic.aspect.service.impl.UserServiceImpl" />

    <bean id="myAround" class="com.aomsir.basic.aspect.MyAspect" />

    <!--告知Spring现在使用注解进行AOP编程-->
    <aop:aspectj-autoproxy />
</beans>

切入点复用

上面的内容确实为我们详细地展示了注解式的AOP开发,但在实际应用中,常常会碰到一个核心的问题:切入点的复用性。想象一下,如果我们要为同一个切入点添加100多种不同的额外功能,按照传统的方式,无疑需要为每一个功能定义相同的切入点表达式,这显然是不现实且效率低下的。

为了解决这一问题,我们可以进一步优化开发流程,抽取切入点进行统一定义。例如,我们可以定义一个名为myPointCut的方法来专门存放切入点表达式。此方法应当具有public的访问权限,返回类型为void,并且不包含任何参数。方法体本身可以是空的 ,其真正的价值在于其上方的@Pointcut注解,这里我们可以书写具体的切入点表达式。

通过这种方式,我们实现了切入点的集中管理,后续只需要在需要的地方引用myPointCut方法即可,无需每次都重新定义相同的切入点表达式。这种策略不仅大大简化了代码结构,还提高了代码的可读性和维护性

java 复制代码
@Aspect
public class MyAspect {
    private static final Logger log = LoggerFactory.getLogger(MyAspect.class);


    /**
     * 抽取切入点,下面的切入点表达式直接引用即可
     * 修饰符为public,返回值为void,方法体为空,方法名为任意即可
     */
    @Pointcut("execution(* login(..))")
    public void myPointCut() {}


    @Around("myPointCut()")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        log.debug("log before");

        // 执行原始方法
        Object ret = joinPoint.proceed();

        log.debug("log after");
        return ret;
    }

    @Around("myPointCut()")
    public Object tx(ProceedingJoinPoint joinPoint) throws Throwable {
        log.debug("tx before");

        // 执行原始方法
        Object ret = joinPoint.proceed();

        log.debug("tx after");
        return ret;
    }
}

切换Cglib

在我们转向基于注解的AOP定义后,切面的相关定义已被整合进切面类,而不再散落在XML文件中。这种做法使得我们的配置更为集中和清晰。但此时,可能会引发一个疑问:当我们决定采用基于注解的方式,如何确保Spring框架使用Cglib作为底层的动态代理实现呢? 其实,答案相当简单。你只需要在XML配置中进行如下修改;对于SpringBoot项目也只需要在启动类上添加注解即可

xml 复制代码
<!--告知Spring现在使用注解进行AOP编程-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
java 复制代码
@EnableAspectJAutoProxy(proxyTargetClass = true)
@SpringBootApplication
public class DemoApplication {

总结

在这篇文章中,我们深入探讨了如何在Spring框架中通过注解进行AOP编程。相比于传统的基于XML的配置方式,注解式AOP为开发者带来了更为直观和简洁的编程体验。通过注解,我们可以清晰地将切面逻辑与业务代码进行解耦,同时还保持了代码的整洁性和可读性。

尽管本文并没有触及SpringBoot的相关内容,但在这个基础上,当我们转向SpringBoot的开发时,可以更为轻松地将今天所学应用到实际的项目中。借助SpringBoot的自动配置特性,我们的AOP开发流程将进一步简化,使得为业务方法增加额外功能变得更为高效和便捷。

希望这篇文章为大家带来了有关Spring AOP注解开发的深入理解,为大家在未来的开发工作中提供了宝贵的参考和指导

参考文献

相关推荐
追逐时光者5 小时前
推荐 12 款开源美观、简单易用的 WPF UI 控件库,让 WPF 应用界面焕然一新!
后端·.net
Jagger_5 小时前
敏捷开发流程-精简版
前端·后端
苏打水com6 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
西瓜er6 小时前
JAVA:Spring Boot 集成 FFmpeg 实现多媒体处理
java·spring boot·ffmpeg
间彧7 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧7 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧7 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧7 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端
间彧7 小时前
Spring Cloud Gateway详解与应用实战
后端
EnCi Zheng8 小时前
SpringBoot 配置文件完全指南-从入门到精通
java·spring boot·后端