图文详解 Spring AOP,看完必懂。。

简介: 图文详解 Spring AOP,看完必懂。。

学习一个模块的设计主要是看接口设计,通过接口设计我们就能够从整体知道模块怎么实现的,具体实现就是组装这些接口来进行实现的,知道了模块接口设计,实现也就变得很简单了。

本文主要从aop背景出发点,来自己去想需要哪些接口,就能够描述一个模块的功能设计规则。


AOP产生背景

使用面向对象编程 ( OOP )有一些弊端,当需要为多个不具有继承关系的对象引人同一个公共行为时,例如日志、安全检测等,我们只有在每个对象里引用公共行为,这样程序中就产生了大量的重复代码,程序就不便于维护了,所以就有了一个对面向对象编程的补充,即面向方面编程 ( AOP ), AOP 所关注的方向是横向的,区别于 OOP 的纵向。


什么是AOP

什么是面向方面编程,3个过程:

  • 找到横切点:首要目标确定在程序的哪个位置进行横切逻辑
  • 横切逻辑(业务代码):横切逻辑代码,这个就是横切业务代码,与aop无关
  • 织入:将横切逻辑织入到横切点


开发者主要关心的是横切逻辑的编写,只需要很少的代码编写确定横切点有哪些,而不需要去为每个横切点添加横切逻辑,不然就是面向对象编程了。


既然是横向的编程,那么在我们的程序中,哪些可以作为横线切入点呢?


看下示例代码:

public class Test {
    public static void main(String[] args) {
        //@1
       B b = new B();
       //@2
       b.method();
       //@3
        B.say();
    }
    static class B {
        //字段
        //@4
        private String name;
        //构造方法
        public B() {
            //@1.1
            }
        //对象方法
        public void method(){
            //@2.2
        }
        //静态方法
        static void say(){
            //@3.3
        }
    }
}

所以我们可以将横切点主要分为两大类:字段、方法。方法又分为很多种,

image.png

横切点有很多地方,从代码上看得见的,有如下几个地方:

  • 使用构造函数创建对象
  • 构造函数执行
  • 对象方法调用
  • 对象方法执行
  • 静态方法调用
  • 静态方法执行
  • 反射读写对象字段


目标1:找到横切点

那么怎么去定义一个横切点呢?怎么用一个接口来描述一个横切点呢?


在Java中,一切皆对象,在Java中一个类有2方面内容:字段、方法(构造函数、对象方法、静态方法),java中使用AccessibleObject来抽象公共行为。方法:就是一段可以执行的程序,一段代码。


所以在横切点接口中,首先一个功能就是返回给用户当前横切点,有两种情况:

  • 如果横切点作用于对象(对象字段、对象方法、构造函数),则不仅需要返回AccessibleObject,还需要返回当前对象,因为调用通过反射调用对象方法需要传入当前对象。
  • 如果横切点作用于类,则仅返回AccessibleObject即可。


另一个接口功能就是要不要考虑在横切点来控制多个横切逻辑的调用。这个可以有框架支持,也可以由横切点控制。这对应的就是责任链模式的API设计。比如tomcat中的Filter链式调用就是以集合形式调用;netty中的Handler组织就是以链表形式。如果是以集合形式调用,则在横切点接口需要定义一个方法来链式调用。(aop联盟的JoinPoint采用是集合形式调用)


那么AOP联盟使用JointPoint接口来定义横切点。

public interface Joinpoint {
 Object proceed() throws Throwable;
 Object getThis();
 AccessibleObject getStaticPart();
}

Object proceed() throws Throwable: 链式调用横切点

Object getThis(); 返回连接点当前对象。如果当前连接点是静态,比如静态方法,则该方法返回null,因为反射不需要对象,而且静态方法是通过类调用的,压根就没有对象,所以返回null。spring aop不支持静态方法的拦截,所以在spring中这里返回的就是目标对象(被代理对象)


AccessibleObject getStaticPart(); 返回连接点静态部分,对于连接点是方法,返回的就是Method对象。


现在对连接点的设计比较清晰了,然后就是对连接点的扩展了,比如可执行程序(构造方法、Method)的子接口,字段的子接口(aop联盟没有定义,只有方法级别的)。


AOP联盟对连接点接口的设计:

image.png

比如在MethodInvocation,就是返回Method。


目标2:横切逻辑(增强)抽象定义

增强的抽象,其实就需要连接点信息,毕竟增强是要投入到一个地方的,所以需要连接点信息。

在aop联盟的接口定义:

image.png

Advice作为一个tag标识,在aop联盟中使用拦截器来作为增强的命名,这里完全可以去掉Interceptor,而直接定义一个MethodAdvice。之所以定义为Interceptor,是因为拦截器命名更符合编程命名规范,让人从命名就知道接口功能。


在MethodInterceptor,传入连接点信息(因为是方法拦截,所以这里是方法级别的连接点接口定义)

Object invoke(MethodInvocation invocation) throws Throwable;


目标3:织入

首先就是怎么织入。织入由两种方案。

  • 静态织入:采用自定义类加载器机制。自定义类加载器根据织入规则在加载class文件期间对class文件动手织入横切逻辑,然后将改动后的class文件交给JVM运行。
  • 动态织入:由多种选择,动态代理(JDK Proxy)、动态字节码生成技术(cglib)


spring采用动态织入。动态织入就是生成代理对象,代理对象中维护了当前连接点所有拦截器,然后调用目标方法时被代理类拦截,在代理类中作aop功能。


来一个完整的流程图:

image.png

Spring AOP的实现基于AOP联盟接口标准设计实现的,全局看下aopalliance有哪些接口以及接口的API设计,我们上面已经分析完了。


AOP联盟的接口很少:

image.png

相关文章
|
2月前
|
XML Java 开发者
Spring Boot中的AOP实现
Spring AOP(面向切面编程)允许开发者在不修改原有业务逻辑的情况下增强功能,基于代理模式拦截和增强方法调用。Spring Boot通过集成Spring AOP和AspectJ简化了AOP的使用,只需添加依赖并定义切面类。关键概念包括切面、通知和切点。切面类使用`@Aspect`和`@Component`注解标注,通知定义切面行为,切点定义应用位置。Spring Boot自动检测并创建代理对象,支持JDK动态代理和CGLIB代理。通过源码分析可深入了解其实现细节,优化应用功能。
119 6
|
1月前
|
XML Java 测试技术
Spring AOP—通知类型 和 切入点表达式 万字详解(通俗易懂)
Spring 第五节 AOP——切入点表达式 万字详解!
99 25
|
1月前
|
XML 安全 Java
Spring AOP—深入动态代理 万字详解(通俗易懂)
Spring 第四节 AOP——动态代理 万字详解!
80 24
|
2月前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
93 8
|
4月前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
114 2
Spring Aop该如何使用
|
4月前
|
监控 安全 Java
什么是AOP?如何与Spring Boot一起使用?
什么是AOP?如何与Spring Boot一起使用?
116 5
|
4月前
|
Java 开发者 Spring
深入解析:Spring AOP的底层实现机制
在现代软件开发中,Spring框架的AOP(面向切面编程)功能因其能够有效分离横切关注点(如日志记录、事务管理等)而备受青睐。本文将深入探讨Spring AOP的底层原理,揭示其如何通过动态代理技术实现方法的增强。
117 8
|
4月前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。
|
4月前
|
XML 监控 安全
深入调查研究Spring AOP
【11月更文挑战第15天】
66 5
|
4月前
|
Java 开发者 Spring
Spring AOP深度解析:探秘动态代理与增强逻辑
Spring框架中的AOP(Aspect-Oriented Programming,面向切面编程)功能为开发者提供了一种强大的工具,用以将横切关注点(如日志、事务管理等)与业务逻辑分离。本文将深入探讨Spring AOP的底层原理,包括动态代理机制和增强逻辑的实现。
82 4