SpringbootAOP详细解释,实现切面编程

本文介绍了AOP编程的概念,如何在SpringBoot中使用AOP分离通用功能,如前置、后置和环绕通知的原理及其实现。重点阐述了如何在SpringBoot项目中添加AOP依赖和配置,并通过代码示例展示了如何定义切面和通知类。
摘要由CSDN通过智能技术生成

首先,我们要先了解一下什么是AOP

  AOP(面向切面编程)是一种编程范式,用于将横切关注点与核心业务逻辑分离开来

我们开发软件时,有些功能在很多地方都需要使用,比如日志记录、安全控制等。传统的方式是在每个需要用到这些功能的地方都编写相应的代码,这样会导致代码重复和维护困难。AOP 提供了一种解决方案,它将这些通用功能从主要业务逻辑中分离出来,形成一个独立的模块。在需要使用这些功能的地方,可以通过简单的配置将这个模块应用到代码中。

简而言之,AOP 可以帮助我们更好地组织代码,提高代码的可维护性和重用性。它将通用功能从业务逻辑中抽离出来,让我们能够更加专注于核心业务逻辑的开发。

(就是在不改变原有代码的基础上,将公共的一部分功能抽离出来,在需要的地方,为代码增加新功能

AOP由以下几个组成部分组成:

1、连接点(JoinPoint):程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等

    在springAOP中,理解为方法的执行(可以为任意方法)(因为Spring AOP仅支持方法级别的连接点)

2、切入点(Pointcut):匹配连接点的式子

   在springAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法

        一个具体方法:com.zq.dao包下的BookDao接口中的无参返回值的sav()方法

        匹配多个方法:所有的save方法、所有的get开头的放法(通配符)所有Dao结尾的任意方法、所有带一个参数的方法。

3、通知(Advice):在切入点处执行的操作,也就是共性的功能

        在springAOP中,功能最终以方法实现

4、通知类:定义通知的类,(包含多个不同的通知)

5、切面(Aspect):描述通知与切入点的对应关系。(使用@Aspect注解标识)

6、目标对象:原始功能去掉共性功能对应的类产生的对象,这种对象无法直接完成最终工作的,也是我们要添加共性功能的对象。

7、代理实现:目标对象无法直接完成工作,需要对其进行功能回填,通过原始对象的代理对象实现(一般我们自定义一个接口,将接口加入到目标对象(方法)中,使切入点对映接口)

使用spring boot代码实现:

1、创建一个spring boot项目,并导入aop的起步依赖:

<!--springboot集成Aop-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
 

2、定义一个切面类,在切面类中实现我们的AOP增强操作。加入@Aspect注解,定义为切面类,并在切面类中,实现通知和切入点的实现,并绑定它们之间的关系。

@Component
@Aspect   //切面类

我们这次实现三种常用的通知类型:

前置通知:@Before

顾明知意,就是在方法执行前,执行通知。

//通知,在方法执行之前
@Before(value = "pointcut1()")
public void PrintTime(){
//当前系统时间
    String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    System.out.println(format);
 System.out.println("前置通知");
}

这是一个前置通知,表明在方法执行之前,先执行功能(打印当前系统时间,并输出一句话)。它的切入点是方法pointcut1(),我们根据这个pointcut1()方法,来设置一个切入点表达式:

//    切入点表达式,使用接口形式
@Pointcut("@annotation(com.example.aoptest.aop.Aop)")
    public void pointcut1() {}

我自定义了一个接口Aop,用来作为切入点。这个接口什么都没写,只是定义了一些运行规则:

@Target(ElementType.METHOD)  //作用在方法上
@Retention(RetentionPolicy.RUNTIME)  //运行时有效
public @interface Aop {
    
}

现在,我们就可以将接口定义在我们要增强的方法上了。如图:

@Aop
public void save(){
    System.out.println("save.............");
}

正常我们这个方法,应该输出"save........",但是在加入了@Aop注解之后,增强的功能就可以使用了,现在相当于,先执行前置通知,再执行原本的操作。都执行完毕之后,这个save方法,才算执行完毕!

在test中就行测试,输出结果如下:

后置通知:@After:在方法运行之后才执行通知

//通知,在方法执行之后
@After("pointcut1()")
public void printHello(){
    System.out.println("后置通知,在方法运行完毕之后才执行。");
}

同样的,这个通知也绑定了切入点表达式pointcut1()。那么,这需要在需要添加功能的方法上加入@Aop注解,就可使用在这部分功能。(为了以示区分,我先将前置通知去掉)运行结果如下:

环绕通知:@Around:可以在方法执行的任意位置运作通知,也是我们最常用到的一种类型。

定义环绕通知的模板如下:

//通知,环绕
    @Around("pointcut3()")
    public Object printObject(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前");
        Object proceed = pjp.proceed();
        System.out.println("环绕后");
        return proceed;
    }

首先,解释一下这个模板: @Around注解,定义这个通知为环绕通知。参数"pointcut3()"代表绑定的切入点表达式。

这里着重解释一下环绕通知运行的流程。

假设A方法引入了环绕通知B,那么程序执行到A方法时。会先跳转到环绕通知B中,先执行B中的代码,环绕通知B有一个参数ProceedingJoinPoint,这个参数很重要,里面有方法A的参数、返回值等。pjp.proceed()代表对这个参数进行放行。(pjp.proceed()的返回值Object  proceed就是目标方法A的返回值,得到这个返回值以后,还可以对目标方法的返回值做进一步的处理。)放行之后,就可以执行A中的操作,A中的操作执行完之后,再返回来执行B中剩余的操作,最后返回一个值proceed ,就是这个方法A最终的返回值

简单画个图:

细节:在执行pjp.proceed()方法时,一定要抛一个异常。因为pjp.proceed()表示执行目标方法,但是我们不知道目标方法有没有异常。通知只是给你做功能增强的,并不负责处理异常,所以,在执行pjp.proceed()方法放行时,强制你抛一个异常。

环绕通知的执行结果如下:

      总结:使用AOP可以帮助我们做代码的无侵入式增强,将共性功能抽离出来做成通知,在需要时加入到目标方法中,减少了代码的耦合性。另外,通知是没有类型的,是一个功能的具体实现。只是在通知方法上加入相应的注解,就可以将该通知定义为不同的类型。本次,我讲解了三种常用的类型(前置、后置、环绕)还有更多的通知类型,大家可以自行试验。

可能之前有的人一直用SSM,使用spring boot有些不熟悉,在 Spring Boot 中加入 AOP 是不需要在启动类加任何注解的,因为在AOP的默认配置属性中,spring.aop.auto 属性默认是开启的,也就是说只要引入了 AOP 依赖后,默认已经增加了 @EnableAspectJAutoProxy。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
SpringBootAOP是指在SpringBoot项目中使用AOP(面向切面编程)来简化开发操作的一种方式。通过引入spring-boot-starter-aop依赖,我们可以使用一些常用的注解来方便地进行AOP开发。在SpringBoot项目中使用AOP可以实现一些功能,比如全局请求日志处理。首先,我们需要在项目中引入相关的依赖,包括spring-boot-starter和spring-boot-starter-aop。然后,我们可以使用AOP的注解来定义切点和切面实现对请求的日志处理等操作。在SpringBoot 2.x中,默认使用Cglib来实现AOP的代理方式,但在Spring5文档中,默认还是使用jdk代理方式。如果对象没有实现接口,则会使用CGLIB代理。因此,在自动注入业务类实现类时,如果使用的是jdk代理方式,可能会报错。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [SpringBootSpring核心AOP详解](https://blog.csdn.net/qq_42263280/article/details/127696254)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v12^insert_chatgpt"}} ] [.reference_item] - *2* [SpringBootAOP的使用](https://blog.csdn.net/weixin_45583303/article/details/118565966)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v12^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张乔24

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值