需要引入额外的 CGLIB 库

发布时间:2025-06-24 18:50:27  作者:北方职教升学中心  阅读量:662


当目标类没有实现任何接口时,Spring 会使用 CGLIB 代理。环绕通知(Around Advice)

  • 3、

    随着软件开发技术的不断进步,面向切面编程(AOP)作为一种重要的编程思想,已经在现代开发中占据了重要地位。Spring-Aop 模块补充

    • 2.1、


      2、AOP 前置概念

    • 2.2、代理范围更广(包括普通类)。
    • 局限性:目标类或方法不能声明为 final,否则无法被继承和代理。

      • 实现方式:创建一个实现了目标接口的代理类,并在方法调用前后插入增强逻辑。当目标对象实现了一个或多个接口时,Spring 会默认选择 JDK 动态代理。Spring-Aop 模块概述
      • 1.2、希望本篇内容能为您打开通往 AOP 世界的大门,也期待您在实际工作中灵活运用所学,将代码的复杂度隐藏于优雅的设计之中,为团队和项目带来更大的价值。
      • 局限性:目标类必须有接口。AOP 前置概念

        首先,我们来确认一些 Spring 使用核心的 AOP 概念和术语。

        Spring AOP 通过灵活的配置和强大的功能,可以轻松地将横切关注点从业务逻辑中分离出来,提高代码的可维护性和可扩展性。

        @AspectpublicclassLoggingAspect{@Before("execution(* com.example.service.*.*(..))")publicvoidlogBefore(JoinPointjoinPoint){System.out.println("Before method: "+joinPoint.getSignature().getName());}}
        2.3.2、
      • 切面(Aspect):切面是 AOP 处理横切关注点的核心单元,它是对 横切逻辑的模块化封装,它包含切点和通知(切面 = 切点 + 通知)。但是,如果 Spring 使用自己的术语,那就更加令人困惑了。前置通知(Before Advice)
      • 2.3.2、Spring AOP的实现
      • 2.3、核心原理以及实战操作,帮助您在实际项目中更加得心应手地运用这一强大工具。需要引入额外的 CGLIB 库。
      • @EnableAspectJAutoProxy:启用 AOP 的自动代理。Spring 配置类
      • 3.5、换句话说横切是问题,切面是解决方案。Spring AOP 模块本身不具备完整的 AOP 能力,需要依赖其他模块和工具(例如 AspectJ 或代理机制)来实现 AOP 功能。
      • @Before:定义一个前置通知,在方法执行前触发。后置通知、依赖引入

        虽然 Spring AOP 是一个模块,但它需要依赖以下组件来完整实现 AOP 功能:

        • Spring 核心模块:必须依赖 Spring 的核心模块(如 spring-contextspring-beans),用于 Bean 的创建和管理。

          @AfterThrowing(pointcut ="execution(* com.example.service.*.*(..))",throwing ="error")publicvoidlogAfterThrowing(JoinPointjoinPoint,Throwableerror){System.out.println("Exception in method: "+joinPoint.getSignature().getName());System.out.println("Exception: "+error);}
          2.3.4、
        • AspectJ(可选):Spring AOP 支持 AspectJ 注解,但必须引入 aspectjweaver库。

          1.3、Spring 业务类
          packagecom.lizhengi.example;importorg.springframework.stereotype.Component;/** * 用户业务类 */@Component// 标记为 Spring 管理的 BeanpublicclassUserService{publicvoidcreateUser(Stringname){System.out.println("User "+name +" created.");}publicvoiddeleteUser(Stringname){System.out.println("User "+name +" deleted.");}}
          3.3、
        2.2、后置通知(After Returning Advice)
      • 2.3.3、Spring 切面类
        packagecom.lizhengi.example;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;importorg.springframework.stereotype.Component;@Aspect// 声明这是一个切面@Component// 标记为 Spring 管理的 BeanpublicclassLoggingAspect{@Before("execution(* com.lizhengi.example.UserService.*(..))")// 定义切点publicvoidlogBefore(){System.out.println("Logging before method execution");}}

        说明:

        1. @Aspect:标记为切面。切面的本质是一个包含横切逻辑的类,定义了横切逻辑执行的时机(通知)和适用的位置(切点)。前置通知(Before Advice)

          在目标方法执行之前执行。

      CGLIB 代理:基于字节码生成技术,由 CGLIB(Code Generation Library)库支持。其目的是让横切逻辑独立于业务代码,提高代码模块化程度。

    • 优点:无需引入额外的库(纯 JDK 实现)。
    • 3.5、依赖引入
    • 3.2、例如,为一个类增加性能监控的能力,不改变原始代码。Spring 业务类
    • 3.3、
    <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.39</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.39</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.22.1</version></dependency></dependencies>
    3.2、

    @AfterReturning(pointcut ="execution(* com.example.service.*.*(..))",returning ="result")publicvoidlogAfterReturning(JoinPointjoinPoint,Objectresult){System.out.println("After returning: "+joinPoint.getSignature().getName());System.out.println("Result: "+result);}
    2.3.3、而 Spring-Core 是 Spring 中的基础模块,它提供了框架运行所必需的核心功能。本篇内容将引导您深入理解 Spring AOP 的基本概念、如果您有任何疑问或见解,欢迎随时交流与探讨!

  • 核心术语(逻辑层面,些概念描述的是 AOP 的基本组成部分):

    • 横切(Cross-cutting Concern):横切是指在程序的多个模块中反复出现的功能或逻辑,通常与业务逻辑无直接关系,但又不可或缺。Spring-Aop 模块介绍
      • 1.1、
      • 切点表达式:execution(* com.example.service.UserService.*(..))表示匹配 UserService中的所有方法。安全控制、有多种类型的通知,如前置通知、Spring-Aop 模块补充
        2.1、事务管理等常见的横切逻辑。后记

        在学习和实践 Spring AOP 的过程中,我们不仅能深入了解其实现机制,还能感受到面向切面编程对开发效率和代码质量的提升作用。Spring-Aop 模块概述

        Spring AOP 模块,是 Spring 提供的一个面向切面编程(Aspect Oriented Programming,AOP)的模块。使用 java.lang.reflect.ProxyInvocationHandler

      • 优点:可以代理没有实现接口的类。
      • 3.4、代理生成速度较慢,但运行时性能较好。通知类型
        • 2.3.1、

        核心术语(实现层面,这些概念描述的是 AOP 的技术实现方式和执行过程):

        • 引入(Introduction): 动态地为目标类添加新的接口或功能,是一种特殊的增强方式。这是因为 Spring AOP 本质上是一个基于代理的 AOP 实现框架,它利用 Spring 容器和其他技术来实现横切逻辑。
        • @ComponentScan:指定要扫描的包,加载所有带有 @Component的类。最终通知(After Advice)
      • 在目标方法执行之后执行,无论方法是否成功执行。例如,一个类中的有多个方法,那么每个方法都是潜在的连接点。代理生成速度较快。如果没有容器,Spring AOP 只能手动配置,使用起来非常受限。Spring 主函数

    • X、Spring-Aop 模块作用
  • 2、Spring 切面类
  • 3.4、类加载时或运行时进行。
  • JDK 动态代理:基于 Java 的内置动态代理机制。通知类型

    Spring AOP 提供了以下几种通知类型,每种通知用于在不同的时间点插入增强逻辑。健壮的应用体系奠定基础。Spring 主函数

    packagecom.lizhengi;importcom.lizhengi.example.AppConfig;importcom.lizhengi.example.UserService;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;publicclassMain{publicstaticvoidmain(String[]args){// 加载 Spring 应用上下文AnnotationConfigApplicationContextcontext =newAnnotationConfigApplicationContext(AppConfig.class);// 获取 UserService 的代理对象UserServiceuserService =context.getBean(UserService.class);// 调用方法,触发 AOP 增强userService.createUser("Alice");userService.deleteUser("Bob");// 关闭上下文context.close();}}

    运行结果:

    Logging before method executionUser Alice created.Logging before method executionUser Bob deleted.

    X、它通过将横切逻辑从业务逻辑中分离出来,使得代码更加清晰、引入)和目标类的代码结合的过程,生成增强后的类对象。

    @Around("execution(* com.example.service.*.*(..))")publicObjectlogAround(ProceedingJoinPointjoinPoint)throwsThrowable{System.out.println("Before method: "+joinPoint.getSignature().getName());Objectresult =joinPoint.proceed();// 执行目标方法System.out.println("After method: "+joinPoint.getSignature().getName());returnresult;}

    3、这是因为 Spring AOP 本质上是一个基于代理的 AOP 实现框架,它利用 Spring 容器和其他技术来实现横切逻辑。

    • 实现方式:通过字节码操作生成一个目标类的子类,并对其方法进行拦截。基于注解的 Spring AOP 开发

    3.1、
  • CGLIB 代理:适用于类代理。Spring-Aop 模块介绍
  • 1.1、

    1.2、织入可以在编译时、不依赖 AspectJ 的编译时或加载时织入器。从初识 AOP 的基础概念到动手实现切面逻辑,每一步都在为我们构建更加清晰、环绕通知(Around Advice)

    在目标方法执行前后都执行,可以完全控制目标方法的执行。后置通知(After Returning Advice)

    在目标方法成功执行之后执行。通过继承目标类生成代理类,覆盖目标类中的方法来实现增强。后置异常通知(After Throwing Advice)

    在目标方法抛出异常后执行。这些连接点是程序中可以插入横切逻辑的位置(例如方法调用)。Spring-Aop 模块依赖

  • 1.3、

    @After("execution(* com.example.service.*.*(..))")publicvoidlogAfter(JoinPointjoinPoint){System.out.println("After method: "+joinPoint.getSignature().getName());}
    2.3.5、

    其中 Spring Beans 模块是对 Spring Bean 进行定义,实现 IOC 基础功能的模块。代理目标对象的接口,而不是类本身。Spring 配置类

    packagecom.lizhengi.example;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration// 声明为配置类@ComponentScan(basePackages ="com.lizhengi")// 自动扫描指定包@EnableAspectJAutoProxy// 启用 AOPpublicclassAppConfig{}

    说明:

    1. @Configuration:标记这是一个 Spring 配置类。基于注解的 Spring AOP 开发
      • 3.1、这些功能通常是 “横向” 作用于程序的各个模块,而不是某个模块的核心业务逻辑的一部分,因此被称为横切关注点。Spring-Aop 模块作用

        Spring AOP 模块本身不具备完整的 AOP 能力,需要依赖其他模块和工具(例如 AspectJ 或代理机制)来实现 AOP 功能。易于维护。


        文章目录

            • 1、
            • 织入(Weaving):将切面逻辑(通知、Spring AOP的实现

              Spring AOP 基于代理实现,主要有两种方式:

              1. JDK 动态代理:适用于接口代理。
              2. 通知(Advice): 通知是在特定连接点处执行的动作。Spring-Aop 模块依赖

                Spring-AOP 模块的依赖有两个,分别是 Spring-Beans 模块和 Spring-Core 模块。环绕通知等。Spring AOP 作为 Spring 框架的核心模块之一,为开发者提供了简单且强大的 AOP 支持,使我们能够以更加优雅的方式处理日志记录、

                通知类型执行时机注解
                前置通知在目标方法执行前@Before
                后置通知在目标方法成功返回后@AfterReturning
                后置异常通知在目标方法抛出异常后@AfterThrowing
                最终通知在目标方法执行后(无论成功与否)@After
                环绕通知在目标方法前后都执行,可控制目标方法的执行@Around
                2.3.1、后记


        1、通过定义一套过滤条件,决定哪些连接点将会被增强(即在这些连接点执行通知)。

      • 代理机制:依赖 JDK 动态代理或 CGLIB 来生成代理对象。后置异常通知(After Throwing Advice)
      • 2.3.4、最终通知(After Advice)
      • 2.3.5、
      • 切点(Pointcut):切点从所有切入点中筛选出需要增强的具体点的过滤条件。Spring 官网的原话是:这些术语并非 Spring 独有,遗憾的是,AOP 术语并不是特别直观。
      2.3、
    2. 连接点(Join Point):连接点就是程序中可以插入切面逻辑的具体点。