SpringBoot工程中 AOP入门实践

1.AOP简介

AOP(Aspect Orient Programming)是一种设计思想,是软件设计领域中的面向切面编程,它是面向对象编程(OOP)的一种补充和完善。实际项目中我们通常将面向对象理解为一个静态过程(例如一个系统有多少个模块,一个模块有哪些对象,对象有哪些属性),面向切面理解为一个动态过程(在对象运行时动态织入一些扩展功能或控制对象执行)。如图:
在这里插入图片描述

 AOP 与 OOP 字面意思相近,但其实两者完全是面向不同领域的设计思想。实际项目中我们通常将面向对象理解为一个静态过程(例如一个系统有多少个模块,一个模块有哪些对象,对象有哪些属性),面向切面的运行期代理方式,理解为一个动态过程,可以在对象运行时动态织入一些扩展功能或控制对象执行。


2.AOP的实现原理

在这里插入图片描述

其中,为目标类型(XxxServiceImpl)创建其代理对象方式有两种(先了解):

第一种方式:借助JDK官方API为目标对象类型创建其兄弟类型对象,但是目标对象类型需要实现相应接口.我这个案例中controller没有实现接口所以代理对象的创建不是用JDK.
第二种方式:借助CGLIB库为目标对象类型创建其子类类型对象,但是目标对象类型不能使用final修饰.

3.AOP相关术语解析 

切面(aspect): 横切面对象,一般为一个具体类对象。
切入点(pointcut):定义了切入扩展业务逻辑的位置(哪些方法运行时切入扩展业务),一般会通过表达式进行相关定义,一个切面中可以定义多个切入点。
通知(Advice): 内部封装扩展业务逻辑的具体方法对象,一个切面中可以有多个通知(在切面的某个特定位置上执行的动作(扩展功能)。
连接点(joinpoint):程序执行过程中,封装了某个正在执行的目标方法信息的对象,可以通过此对象获取具体的目标方法信息,甚至去调用目标方法。连接点与切入点定义如图所示:
说明:我们可以简单的将机场的一个安检口理解为连接点,多个安检口为切入点,安全检查过程看成是 通知。总之,概念很晦涩难懂,多做例子,做完就会清晰。先可以按白话去理解。


4.AOP入门案例实践

4.1pom文件中添加依赖

说明:AOP的切入点的选择可以是任意的--AOP--controller--AOP--service--AOP--dao等,我这里选择在controller和service之间.

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

我们选择用启动类来启动demo所以要添加springBoot的starter依赖,然后添加aop的依赖

4.2创建demo的启动类

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

 4.3创建controller

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

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

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

注解@Retention可以用来修饰注解,是注解的注解,称为元注解。
Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型,
这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 RententionPolicy使用。RetentionPolicy有3个值:CLASS  RUNTIME   SOURCE
按生命周期来划分可分为3类:
1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。

@Target:注解的作用目标

@Target(ElementType.TYPE)——接口、类、枚举、注解
@Target(ElementType.FIELD)——字段、枚举的常量
@Target(ElementType.METHOD)——方法
@Target(ElementType.PARAMETER)——方法参数
@Target(ElementType.CONSTRUCTOR) ——构造函数
@Target(ElementType.LOCAL_VARIABLE)——局部变量
@Target(ElementType.ANNOTATION_TYPE)——注解
@Target(ElementType.PACKAGE)——包


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


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

    /**
     * Around 通知,在此通知内部可以定义我们扩展业务逻辑,还可以调用目标执行链
     * @param joinPoint 连接点(通知方法与目标方法的连接点对象)
     *         ProceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("doLog()")
    public Object doAround(ProceedingJoinPoint joinPoint)
            throws Throwable {//通过ProceedingJoinPoint可以找到doSayHello方法
        System.out.println("Before:"+System.currentTimeMillis());
        Object result = joinPoint.proceed();//执行链(其他切面,目标对象方法)
        System.out.println("After:"+System.currentTimeMillis());
        return result;
    }
}

4.6测试结果

 

 4.7通知业务方法的原理

在这里插入图片描述

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

诗人在流浪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值