SpringBoot_____之____AOP应用实践

本文介绍了AOP(面向切面编程)的概念,作为OOP的补充,它允许在不修改原有代码的情况下进行功能扩展。通过JDK动态代理和CGLIB实现AOP,详细讲解了切面、切入点、通知等核心概念,并通过一个具体的日志记录切面示例展示了AOP在Spring框架中的应用。同时,讨论了AOP中切面的定义、通知类型以及SpringBoot默认的AOP代理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:基于OCP(开闭原则-对扩展开放对修改关闭)设计原则对功能进行扩展
基于继承方式实现功能扩展,代码简单,容器理解,但是不够灵活,耦合性比较强。
基于组合方式实现功能扩展,代码比较灵活,耦合低,稳定性强,但理解相对比较困难,代码繁琐。

一. AOP简介

AOP(Aspect Orient Programming)是一种设计思想,是软件设计领域中的面向切面编程,它是面向对象编程(OOP)的一种补充和完善。

二. 实现原理

AOP可以在系统启动时为目标类型创建子类或兄弟类型对象,这样的对象我们通常会称之为动态代理对象
在这里插入图片描述
第一种方式:借助JDK官方API为目标对象类型创建其兄弟类型对象,但是目标对象类型需要实现相应接口.
第二种方式:借助CGLIB库为目标对象类型创建其子类类型对象,但是目标对象类型不能使用final修饰.

三. 相关术语分析

切面(aspect) :

横切面对象,一般为一个具体类对象。

切入点(pointcut) :

定义了切入扩展业务逻辑的位置(哪些方法运行时切入扩展业务),一般会通过表达式进行相关定义,一个切面中可以定义多个切入点。

通知(Advice) :

内部封装扩展业务逻辑的具体方法对象,一个切面中可以有多个通知(在切面的某个特定位置上执行的动作(扩展功能)。

连接点(joinpoint) :

程序执行过程中,封装了某个正在执行的目标方法信息的对象,可以通过此对象获取具体的目标方法信息,甚至去调用目标方法。

四. 通知类型

Spring框架AOP模块定义通知类型,有如下几种:

@Around (优先级最高的通知,可以在目标方法执行之前,之后灵活进行业务拓展.)
@Before (目标方法执行之前调用)
@AfterReturning (目标方法正常结束时执行)
@AfterThrowing (目标方法异常结束时执行)
@After(目标方法结束时执行,正常结束和异常结束它都会执行)

五. 操作流程

5.1 添加AOP依赖

  <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-aop</artifactId>
   </dependency>

5.2 创建注解类型,应用于切入点表达式的定义

package com.jt.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiredLog {
    String value() default "";
}

5.3 创建切面对象,用于做日志业务增强

package com.jt.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @Aspect 注解描述的类称为切面对象,此对象中负责定义切入点和通知
 * 1.切入点(在哪些方法执行时,进行功能扩展)
 * 2.通知(所有的扩展逻辑,都写到通知方法中)
 *
 */
@Aspect
@Component
public class LogAspect {
    /**
     * @Pointcut定义切入点,表达式多种,常用注解表达式
     * 当使用自己的写的注解对方法描述时,这个方法就是切入点方法.
     */
    @Pointcut("@annotation(com.jt.aop.RequiredLog)")
     public void doLog(){}  //这个方法主要承载切入点

    /**
     * @Around注解描述的方法,可以在切入点执行之前和之后进行业务拓展,
     * @param joinPoint 连接点对象,此对象封装了要执行的目标方法信息.
     * @return
     * @throws Throwable
     */

    @Around("doLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("Before:"+System.currentTimeMillis());
        Object result = joinPoint.proceed();//执行链(其它切面,目标对象方法)
        System.out.println("After:"+System.currentTimeMillis());
        return result;
    }

}

5.4 通过注解RequiredLog注解描述日志查询或删除业务相关方法,此时这个方法为日志切入点方法

package com.jt.web.controller;

import com.jt.aop.RequiredLog;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/demo")
public class DemoController {
    @RequiredLog    //由次注解描述的方法是切入点方法
    @GetMapping
    public String doSayHello(){
        return "hello spring";
    }
}

六. FAQ分析

AOP中切面的定义需要注意什么?(@Aspect,@Component)
AOP 切面中都需要定义什么?(切入点,通知方法)
AOP中切面可以有多个吗?(可以)
AOP中多个切面可以作用于同一个切入点方法吗?(可以)
AOP中通知方法的应用类型哪些,分别是什么时间点执行?
SpringBoot中默认AOP代理对象创建方式?(CGLIB-更加灵活)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值