Spring 面向切面编程 第4关:AOP实现原理-CgLib动态代理

article/2025/10/3 13:02:10

目录

任务描述

相关知识

代理模式(Proxy)

AOP实现的两种方式

CGLIB动态代理步骤

模拟AOP实现

代理类说明

编程要求

测试说明

参考代码


任务描述

我们知道,Spring AOP的主要作用就是不通过修改源代码的方式、将非核心功能代码织入来实现对方法的增强。那么Spring AOP的底层如何实现对方法的增强? 本关任务:本关将带你学习CGLIB代理模拟AOP实现。

相关知识

CGLIB代理模拟AOP实现主要是采用字节码增强框架cglib,在运行时创建目标类的子类,从而对目标类进行增强。

为了完成本关任务,你需要掌握:如何使用CGLIB代理模拟AOP实现。

代理模式(Proxy)

代理模式就是给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用,在不改变目标对象方法的情况下对方法进行增强。

AOP实现的两种方式

通过前两个关卡的学习,我们知道切面类中的方法会根据相应的策略对目标对象进行增强,那么这是怎么实现的呢?答案就是AOP使用了动态代理,Spring AOP使用JDK动态代理或CGLIB为给定目标对象创建代理。如果要代理的目标对象实现了至少一个接口,则AOP默认使用JDK动态代理,否则使用CGLIB代理。

CGLIB动态代理步骤

  • 定义一个org.springframework.cglib.proxy.MethodInterceptor接口的实现类,重写intercept方法;
  • 获取org.springframework.cglib.proxy.Enhancer类的对象;
  • 分别调用Enhancer对象的setSuperclasssetCallback方法,使用create方法获取代理对象;
  • 通过代理对象调用目标方法。

模拟AOP实现

  • 创建目标类

    1. public class User {
    2. @Override
    3. public void addUser(){
    4. System.out.println("增加用户");
    5. };
    6. }
  • 创建切面类

    1. public class Authority {
    2. public void before() {
    3. System.out.println("程序执行前的时间");
    4. }
    5. public void after() {
    6. System.out.println("程序执行后的时间");
    7. }
    8. }
  • 创建代理类

    1. public class MyProxy {
    2. public static User createUserService(){
    3. //目标类
    4. User userService = new User();
    5. //切面类
    6. Authority authority = new Authority();
    7. //cglib核心类
    8. Enhancer enhancer = new Enhancer();
    9. enhancer.setSuperclass(userService.getClass());
    10. enhancer.setCallback(new MethodInterceptor() {
    11. @Override
    12. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    13. //目标方法执行前
    14. authority.before();
    15. //放行目标方法
    16. Object invoke = methodProxy.invokeSuper(o,objects);
    17. //目标方法执行后
    18. authority.after();
    19. return invoke;
    20. }
    21. });
    22. User proxy = (User) enhancer.create();
    23. return proxy;
    24. }
    25. }
  • 创建测试类

    1. public class Test {
    2. public static void main(String[] args) {
    3. User userService = MyProxy.createUserService();
    4. userService.addUser();
    5. }
    6. }
  • 输出结果: 程序执行前的时间 增加用户 程序执行后的时间

代理类说明

如上所示,我们获取Enhancer类的对象,分别调用Enhancer对象的setSuperclasssetCallback方法(重写intercept方法),最后使用create方法获取代理对象

编程要求

请仔细阅读右侧代码,根据方法内的提示,在 Begin - End 区域内进行代码补充,完成模拟 AOP 实现。即在目标类调用updateNameAndPw()方法前先执行切面类的before()方法。updateNameAndPw()方法会输出更新用户名和密码before()方法会输出权限校验。 目标类:UserServiceImpl 代理类:MyProxy 切面类:Authority 以上类在右侧代码文件处可见。 后台会自动创建代理类对象,并调用目标类中的updateNameAndPw()方法。

测试说明

补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

预期输出:

权限校验

更新用户名和密码


开始你的任务吧,祝你成功!

参考代码

package educoder;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class MyProxy {public static  UserServiceImpl createUserService(){//请在以下提示框内填写你的代码/**********Begin**********///目标类UserServiceImpl userService = new UserServiceImpl();//切面类Authority authority = new Authority();//cglib核心类Enhancer enhancer = new Enhancer();enhancer.setSuperclass(userService.getClass());enhancer.setCallback(new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {//目标方法执行前authority.before();                //放行目标方法Object invoke = methodProxy.invokeSuper(o,objects);//目标方法执行后return  invoke;}});//获取代理对象UserServiceImpl proxy = (UserServiceImpl) enhancer.create();//返回代理对象return proxy;/**********End**********/}
}

 


http://chatgpt.dhexx.cn/article/rjK0sIgU.shtml

相关文章

Spring AOP实现原理详解之Cglib代理实现

引入 我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理。 要了解动态代理是如何工作的,首先需要了解 什么是代理模式?什么是…

Spring——AOP用到的代理模式SpringAOP实现原理

AOP,面向切面编程,是Spring框架中的核心思想之一;在Spring中是通过动态代理来实现的,在目标类的基础上增加切面逻辑,对原对象进行增强; SpringAOP的源码中用到了两种动态代理来实现拦截切入功能&#xff1…

深入分析 Spring 基于注解的 AOP 实现原理

一、AOP 的基本使用 AOP 的使用分为三步走: 将业务逻辑组件和切面类都加入到容器中:告诉 Spring 哪个是切面类;Aspect在切入类上的每一个通知方法上标注通知注解:告诉 Spring 何时何地运行(切入点表达式)…

灵魂画手图解Spring AOP实现原理!

本篇旨在让读者对Spring AOP实现原理有一个宏观上的认识,因此会丢失一些细节,具体实现参考:老实人Spring源码目录 阅读本篇文章前,希望读者对Spring Ioc以及Spring AOP的使用(Aspect)由一定了解,话不多说,直…

Spring AOP实现原理

1、Spring AOP Spring AOP的面向切面编程,是面向对象编程的一种补充,用于处理系统中分布的各个模块的横切关注点,比如说事务管理、日志、缓存等。它是使用动态代理实现的,在内存中临时为方法生成一个AOP对象,这个对象…

AOP实现原理详解

 转载地址:https://my.oschina.net/elain/blog/382494 一、什么是 AOP AOP(Aspect-OrientedProgramming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向…

Spring框架的AOP实现原理

一、AOP的基本概念 AOP先是一种思想,后是一种技术。 AOP:面向切面编程,是将那些与业务无关(比如有事务处理,日志管理,权限控制等),但要为业务模块共同调用的逻辑封装成一个可重用的…

Java:由浅入深揭开 AOP 实现原理

概述: 最近在开发中遇到了一个刚好可以用AOP实现的例子,就顺便研究了AOP的实现原理,把学习到的东西进行一个总结。文章中用到的编程语言为kotlin,需要的可以在IDEA中直接转为java。 这篇文章将会按照如下目录展开: A…

Spring的AOP原理

为什么80%的码农都做不了架构师?>>> 一、什么是 AOP AOP(Aspect-OrientedProgramming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完…

利用C语言实现动态数组

数组存在的问题:如果我们定义一个数组去存储数据,需要提前定义数组的个数,或者数组根据第一次存储的元素个数自动确定数组的大小,但是我们如果想对数组进行元素插入只能重新定义一个新数组,或者预定义一个空间非常大的…

C++数组之动态数组

目录 1.摘要 2.动态数组内存分配 1一维数组 2多维数组(以2维为例) 3.动态数组初始化 1默认初始化 2.自定义初始化 4.动态数组释放 5.例子 Gradebook类的实现 6.参考文章 1.摘要 数组是一种顺序存储的数据结构,在定义数组时&…

C++中如何定义动态数组

首先:为什么需要动态定义数组呢? 这是因为,很多情况下,在预编译过程阶段,数组的长度是不能预先知道的,必须在程序运行时动态的给出 但是问题是,c要求定义数组时,必须明确给定数组…

c++ 动态数组

动态数组 相关数组知识连接 数组详解 多维数组 在之前的文章中,讲解了数组的相关知识,那一种数组(数组相关连接:https://blog.csdn.net/m0_62870588/article/details/123787052)又称是静态数组,因为它的大小…

C语言中动态分配数组

很多人在编写C语言代码的时候很少使用动态数组,不管什么情况下通通使用静态数组的方法来解决,在当初学习C语言的时候我就是一个典型的例子,但是现在发现这是一个相当不好的习惯,甚至可能导致编写的程序出现一些致命的错误。尤其对…

C语言学习笔记:动态数组

动态数组 数组是C语言中的很重要的一种构造类型,最初我们学习的都是静态数组,但是,静态数组有着自己难以改变的缺点——数组长度固定。 一般在静态数组定义后,系统就会为其分配对应长度的连续的专有内存空间,可是&am…

C语言如何实现动态数组?

提出问题 请问在c语言里如何实现动态大小的数组啊,比如说int a[N];,这里N的值可以在程序中定,或者有什么方法可以实现类似的功能?总之只要在编译时不用制定数组大小就行。 分析问题 嵌入式系统的内存是宝贵的,内存是否…

C的动态数组的详细知识(网上收集到的大量详细知识以及个人理解的汇总)

动态数组是指在声明时没有确定数组大小的数组,即忽略圆括号中的下标;当要用它时,可随时用ReDim语句重新指出数组的大小。使用动态数组的优点是可以根据用户需要,有效利用存储空间。 可以了解动态数组的详细定义 一.C版本动态数组…

动态数组C语言实现详解

目录 0、前言 一、动态数组数据结构 二、动态数组增删改查函数声明 三、数组创建 1、头部动态创建 2、头部静态创建 四、元素添加 五、元素删除 1、根据元素值删除 2、根据元素位置删除 六、元素修改 七、元素查找 八、数组清空 九、数组销毁 十、验证程序 0、前…

C语言实现 动态数组 处理任意类型数据

引言:动态数组在C/C、Java、Python等语言中应用广泛,高级语言一般通过调用类或接口等可以快捷使用,C语言实现动态数组需要手动构造,以下为实现过程。 1 结构体构造动态数组 typedef struct Array {void **p; //维护在堆区…

C语言创建动态数组

C语言创建动态数组 1.编写步骤 1. 添加所需头文件 stdlib.h 该头文件下包含的与分配存储区相关的函数如下: void* malloc (size_t size);//从堆中分配size字节的存储空间 void* calloc (size_t num, size_t size);//分配数组并将数组零初始化。为 num 个元素的数…