Spring AOP学习

概述

  1. 软件开发的目的是为了解决各种真实场景的业务和系统需求。面向对象能对现实世界能够对代码结构进行地抽象与封装,让系统有很好地模块化,扩展性和可维护性。
  2. 需求与具体实现之间的关系上一对一,但是在系统开发过程中往往会存在一些切面,切面通常与系统逻辑无关,是面向多个或者所有的需求线的一个面。现在我们需要一种能够将这种横切面与业务逻辑解耦的一种方法,那就是AOP,即面向切面编程。
  3. 但是AOP通常并不能被作为一种主要的开发方式,毕竟建立起一个业务系统主要还是得靠复杂而繁多的业务逻辑。我们通常会使用OOP的方法来开发业务逻辑。而AOP只能一个依附于OOP的一种特性。即是没有AOP我们也能工作,但是有AOP我们能够做得更好。

静态与动态

静态AOP:在程序运行之前的编译期,将各个切面以字节码的形式编译到各个功能模块中。切面以字节码的形式编译到Java类中,Java虚拟机可以像通常一样加载Java类运行,不会对整个系统的运行造成任何的性能损失。 但是每一次切入点需要更改关注点的位置,就需要使用编译器重新编译Aspect重新织入到系统的位置。

动态AOP:通过Java语言提供的各种动态特性来实现Aspect织入到当前系统。AOP的各种实体都是普通的Java类,AOP的织入过程在系统运行开始之后进行,而不是在预编译到系统中。织入信息式大多以XML和注解的形式保存,在修改织入点的同时不必变更系统的其他模块。另一方面,动态AOP的织入时机大多在类加载或者系统运行时,因此动态AOP会对系统造成一定的性能损失。

Java的AOP实现机制

动态代理:通过Java的动态代理来实现AOP, 在运行时为对应的接口生成代理对象,我们开发可以将切面的逻辑封装在动态代理的InvocationHandlder中。所有的被代理的对象必须实现接口。如果某些系统并不遵循面向接口编程,那么Java的动态代理不被支持。

动态字节码:通过ASM或者CGlib等工具在程序运行时生成字节码的class文件,为这些系统的模块类添加子类,通过子类达到将横切面织入系统的目的。程序没有实现接口同样可以进行代理。但是如果被代理的方法被生命未final,那么也不能支持代理类的生成。

代码生成:使用工具,根据描述文件,自动生成被代理的对象。方式在开发中生成。

自定义类加载器:自定义的类加载器通过读取外部文件规则的织入规则和必要的信息,在加载class期间可以将横切面的逻辑添加到系统模块现有的逻辑中。然后将改动的class交给虚拟机执行就是了。通过这种貌似可以实现基于方法体内部的横切面。可谓是功能非常强大。

AOL扩展:属于一种新的 AOP 语言,能够实现几乎所有的横切面类型。但是学习成本过高。

AOP的几大角色

实现AOP需要的几大角色:JoinPoint, PointCut , Advice, Aspect

  • JoinPoint
    在系统运行之前,我们需要知道系统的哪些执行点需要上进行织入操作,这些执行点就被称为JoinPoint。程序中可以认为必要的执行点都可以认为了JoinPoint,常见的JoinPoint分为下面几类:
    ① 方法调用, 当方法被调用的时候的执行点。在方法执行之前后。是最常用的一种JoinPoint。
    ② 方法执行调用, 在方法执行之中的执行点,需要切入到方法逻辑内部
    ③ 构造方法, 在构造实例之前、之间、之后的切入点。
    ④ 字段设置、获取, 对象的字段通过setter或者getter、或者直接赋值、反射设置属性时。
    ⑤ 异常处理执行,在某种类型的异常被跑出时会执行。
    ⑥ 类初始化,指代类中的某些静态类型或者静态代码块的初始化点。
  • PointCut
    对于需要被关注的横切面的表述语言。比如一个检查用户登录的PointCut则需要描述系统中的哪些Controller需要被织入。常见的PointCut的表述方式:
    ① 直接指定JointPoint所在的方法
    ② 正则表达式,执行方法满足的正则表达式
    ③ PointCut表达式,一种类似于正则表达式的语言,通常PointCut的表达式都会使用这种
    ④ 注解扫描。扫描被注解了某个注解的方法,将这些方法纳入到切面。
  • Advice
    Advice是对于关注点的横切逻辑,按照Advice在PointCut的位置会有不同的功能。具体地可分为下列的多种:
    ① 前置通知 Before Advice 在方法执行之前执行的横切逻辑
    ② 后置通知 After Advice 在方法执行之后执行的横切逻辑
    ③ 环绕通知 Around Advice 会环绕整个方法执行的横切逻辑,包含前置,后置,异常所有特性
    ④ Introduction 可以为原有的对象添加新的特性或者行为,并不是按照实际来区分不同的通知类型
  • Aspect
    Aspect是一个切面的概念实体。通常在一个Aspect中会定义PointCut的描述、执行Advice的逻辑、以及在Advice中会包含的JoinPoint逻辑。因此,相当于Aspect即可以包含一个切面的所有内容的组合体。在Java中,Aspect就是一个Java的类

基本实现

  1. 代理模式
public interface IRequest {
   
    void request();
}
public class RequestImpl implements IRequest{
   
    @Override
    public void request() {
   
        System.out.println("request");
    }
}
public class RequestProxy implements IRequest {
   
    private IRequest request;
    public RequestProxy(IRequest request) {
   
        this.request = request;
    }
    @Override
    public void request() {
   
        System.out.println("before...");
        request.request();
        System.out.println("after...");
    }
}
public class Client {
   
    public static void
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值