• 【Spring】Spring AOP的实现原理


    目录

    什么是AOP

    AOP的作用        

    AOP的优点

    AOP框架

    Spring AOP

    AspectJ

    术语

    1.Target ——目标类

    2.Joinpoint ——连接点

    3.Pointcut——切入点

    4.Advice——通知/增强

    5.Weaving——植入

    6.Proxy——代理类

    7.Aspect——切面

    底层逻辑

    开发流程

    1.导入依赖

    2.开启命名空间

    3.定义方法

    4.自定义类实现

    5.定义切入点

    注解开发


    什么是AOP

            AOP 即面向切面编程,和 OOP(面向对象编程)类似,也是一种编程思想

    AOP的作用        

            AOP 采取横向抽取机制(动态代理),取代了传统纵向继承机制的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。

            主要作用是分离功能性需求和非功能性需求,使开发人员可以集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入增强代码的可读性和可维护性

            简单的说,AOP 的作用就是保证开发者在不修改源代码的前提下,为系统中的业务组件添加某种通用功能。AOP 就是代理模式的典型应用

    AOP的优点

            AOP 是 Spring 的核心之一,在 Spring 中经常会使用 AOP 来简化编程。在 Spring 框架中使用 AOP 主要有以下优势。

    • 提供声明式企业服务,特别是作为 EJB 声明式服务的替代品。最重要的是,这种服务是声明式事务管理。

    • 允许用户实现自定义切面。在某些不适合用 OOP 编程的场景中,采用 AOP 来补充。

    • 可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时也提高了开发

    AOP框架

            目前最流行的 AOP 框架有两个

    Spring AOP

    • Spring AOP 是基于 AOP 编程模式的一个框架,它能够有效的减少系统间的重复代码,达到松耦合的目的。
    • Spring AOP 使用纯 Java 实现,不需要专门的编译过程和类加载器,在运行期间通过代理方式向目标类植入增强的代码。
    • 有两种实现方式:基于接口的 JDK 动态代理和基于继承的 CGLIB 动态代理。

    AspectJ

    • AspectJ 是一个基于 Java 语言的 AOP 框架,从 Spring 2.0 开始,Spring AOP 引入了对 AspectJ 的支持。AspectJ 扩展了 Java 语言,提供了一个专门的编译器,在编译时提供横向代码的植入。
    • 扩展了Java语言 提供了一门编译器 ,在编译时提供横向的代码织入

    术语

    名称说明
    Target(目标)指代理的目标对象。
    Pointcut(切入点)指要对哪些 Joinpoint 进行拦截,即被拦截的连接点。
    Advice(通知)指拦截到 Joinpoint 之后要做的事情,即对切入点增强的内容。
    Joinpoint(连接点)指那些被拦截到的点,在 Spring 中,指可以被动态代理拦截目标类的方法。
    Weaving(植入)指把增强代码应用到目标上,生成代理对象的过程。
    Proxy(代理)指生成的代理对象。
    Aspect(切面)切入点和通知的结合。

    1.Target ——目标类

            需要被代理的类,比如:userService。

    2.Joinpoint ——连接点

            是指那些可能被拦截的方法 比如:所有的方法。

    3.Pointcut——切入点

            已经被增强的连接点,在哪些类上,哪些方法上切入。

    4.Advice——通知/增强

            增强代码 (前置通知 、后置通知、返回后通知 、抛出异常通知、环绕通知)。

            在方法执行的什么时候( 之前 之后 ...)做什么事情(方法)去。

    通知说明
    before(前置通知)通知方法在目标方法调用之前执行
    after(后置通知)通知方法在目标方法返回或异常后调用
    after-returning(返回后通知)通知方法会在目标方法返回后调用
    after-throwing(抛出异常通知)通知方法会在目标方法抛出异常后调用
    around(环绕通知)通知方法会将目标方法封装起来

    5.Weaving——植入

            把增强的方法应用到目标对象Target 来创建新的代理对象Proxy的过程。

    6.Proxy——代理类

    7.Aspect——切面

            是切入点(Pointcut)和通知(Advice)的结合,即在什么时候,什么地方,做什么增强。

    底层逻辑

     

    开发流程

    1.导入依赖

    1. <dependency>
    2. <groupId>org.aspectjgroupId>
    3. <artifactId>aspectjweaverartifactId>
    4. <version>1.9.7version>
    5. dependency>

    2.开启命名空间

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:aop="http://www.springframework.org/schema/aop"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans-xxx.xsd
    7. http://www.springframework.org/schema/aop
    8. http://www.springframework.org/schema/aop/spring-aop-xxx.xsd ">
    9. beans>

    3.定义方法

    1. public void beforeAdvice(JoinPoint jp) {
    2. System.out.println("基于Spring AOP的前置增强处理.....");
    3. }
    4. public void afterReturnAdvice() {
    5. System.out.println("基于Spring AOP的后置返回增强处理.....");
    6. }
    7. public void afterAdvice() {
    8. System.out.println("基于Spring AOP的后置增强处理.....");
    9. }
    10. public void afterThrowAdvice() {
    11. System.out.println("基于Spring AOP的异常返回增强处理.....");
    12. }
    13. public Object aoundAdvice(ProceedingJoinPoint pt) {
    14. System.out.println("基于Spring AOP的环绕增强前置处理.....");
    15. Object res = null;
    16. try {
    17. res=pt.proceed();//调用目标方法 返回目标方法的返回结果
    18. } catch (Throwable e) {
    19. e.printStackTrace();
    20. }
    21. System.out.println("基于Spring AOP的环绕增强后置处理.....");
    22. return res;
    23. }

    4.自定义类实现

    1. <bean id="xxx" class="xxx.xxx"/>
    2. <aop :config>
    3. <aop:aspect ref="xxx">
    4. ​ ...
    5. aop:aspect>
    6. aop:config>

    5.定义切入点

        用来定义一个切入点,当 元素作为 元素的子元素定义时,表示该切入点是全局切入点,它可被多个切面所共享;当 元素作为 元素的子元素时,表示该切入点只对当前切面有效。

    1. <aop :config>
    2. <aop:pointcut id="point" expression="execution(* com.yjy.service.UserServiceImpl.*(..))"/>
    3. <aop:aspect ref="diyPoint">
    4. <aop:pointcut id="point" expression="execution(* com.yjy.service.UserServiceImpl.*(..))"/>
    5. <aop:before pointcut-ref="point" method="..."/>
    6. <aop:after-returning pointcut-ref="point" method="..."/>
    7. <aop:around pointcut-ref="point" method="..."/>
    8. <aop:after-throwing pointcut-ref="point" method="..."/>
    9. <aop:after pointcut-ref="point" method="..."/>

    注解开发

            在 Spring 中,尽管使用 XML 配置文件可以实现 AOP 开发,但是如果所有的相关配置都集中在配置文件中,势必会导致 XML 配置文件过于臃肿,从而给维护和升级带来一定的困难。

    名称说明
    @Aspect用于定义一个切面。
    @Pointcut用于定义一个切入点。
    @Before用于定义前置通知,相当于 BeforeAdvice。
    @AfterReturning用于定义后置通知,相当于 AfterReturningAdvice。
    @Around用于定义环绕通知,相当于MethodInterceptor。
    @AfterThrowing用于定义抛出通知,相当于ThrowAdvice。
    @After用于定义最终final通知,不管是否异常,该通知都会执行。
    @DeclareParents用于定义引介通知,相当于IntroductionInterceptor(不要求掌握)。
    1. @Before(value = "execution(* com.yjy.spring.impl..(..))")

    2. @After(value = "execution(* com.yjy.spring.impl..(..))")

    3. @AfterReturning(value="execution(* com.yjy.service.impl..(..))")

    4. @AfterThrowing(value="execution(* com.yjy.service.impl..(..))")

    5. @Around(value="execution(* com.yjy.service.impl..(..))")

  • 相关阅读:
    我的第一个 Intellij 插件上线了
    计算机系统基础知识-经典题目
    【let var const】
    基于SpringBoot的大型商场应急预案管理系统
    Hive表新增字段值为NULL问题
    c#中的扩展方法
    介绍 TensorFlow 的基本概念和使用场景。
    java计算机毕业设计废品回收管理系统设计与实现MyBatis+系统+LW文档+源码+调试部署
    漫谈:C/C++ char 和 unsigned char 的用途
    Time-Frequency Signal Analysis and Processing 笔记
  • 原文地址:https://blog.csdn.net/weixin_46005032/article/details/127926995