Sping框架 动态代理 AOP
动态代理是一种实现 AOP(面向切面编程)的方式,它可以在运行时动态地生成代理对象,从而实现对目标对象的增强。
具体来说,动态代理可以在不修改原有代码的情况下,为目标对象的方法添加前置通知、后置通知、异常通知、环绕通知等横切逻辑。
Java 中的动态代理主要有两种实现方式:基于接口的动态代理和基于类的动态代理。它们都是通过 Java 提供的 java.lang.reflect 包中的 Proxy 类和 InvocationHandler 接口来实现的。
基于接口的动态代理是指在运行时动态地生成一个实现了指定接口的代理类,代理类会实现 InvocationHandler 接口的 invoke 方法,通过反射机制来调用目标对象的方法,并在调用前后添加相应的横切逻辑。
基于接口的动态代理需要目标对象实现一个接口,因此它的适用范围比较有限。 基于类的动态代理是指在运行时动态地生成一个继承了指定类的代理类,代理类同样会实现 InvocationHandler 接口的 invoke 方法,通过反射机制来调用目标对象的方法,并在调用前后添加相应的横切逻辑
。基于类的动态代理不需要目标对象实现接口,因此它的适用范围更广。 动态代理的使用需要定义一个 InvocationHandler 对象,该对象实现 invoke 方法,用于定义目标对象方法的增强逻辑。
然后通过 Proxy 类的 newProxyInstance 方法来生成代理对象,该方法需要传入目标对象的类加载器、目标对象实现的接口(如果是基于接口的动态代理)或目标对象的类(如果是基于类的动态代理)以及 InvocationHandler 对象。
总之,动态代理是一种非常有用的技术,它可以帮助我们实现 AOP 编程,提高程序的可扩展性和可维护性。
我们可以把这些功能封装成一个增强方法,然后在功能方法中进行调用,但是也出现了方法的十处、一百处的调用操作,一旦增强方法名字改变,就需要完成所有调用处代码的修改。或者有一天不需要这些增强操作
在Java开发中如果一个类中的方法在基本功能之外需要进行功能扩充或者功能增强,如:事务控制、权限判断、日志记录等等操作,此时可以使用动态代理机制。
定义实现接口的子类,实现接口定义的方法,此方法只需要把核心功能实现即可,其他增强的操作可以在代理类中实现。
基于子类的CGLib动态代理,可以使用Enhancer类完成直接对某个类进行动态代理。具体操作步骤如下:
- 创建被代理的类,并且定义功能方法,只需要完成核心功能即可。
- 定义代理类,使用Enhancer创建代理对象,对被代理对象进行方法增强。
AOP
AOP的相关术语
- Joinpoint(连接点):
所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的连接点。
- Pointcut(切入点):
所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
- Advice(通知/增强):
所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
- Introduction(引介):
引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field。
- Target(目标对象):
代理的目标对象。
- Weaving(织入):
是指把增强应用到目标对象来创建新的代理对象的过程。spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。
- Proxy(代理):
一个类被 AOP 织入增强后,就产生一个结果代理类。
- Aspect(切面):
是切入点和通知(引介)的结合。
AOP,全称为Aspect-Oriented Programming,即面向切面编程。
AOP 是基于 OOP(面向对象编程)的一种编程思想,旨在通过将与业务无关的横切关注点(如日志、事务、权限等)与业务逻辑(如增删改查等)进行分离,从而提高代码的可复用性、可维护性和可扩展性。
在 AOP 中,切面(Aspect)是一个横切关注点的模块化,并将切面织入到业务逻辑中,可以减少代码的重复性、提高代码的可维护性和可扩展性。
它们可以被应用到对象模型的任何位置。切面使用一个称为通知(Advice)的代码片段来描述它们所关注的横切关注点,并定义了一组切点(Pointcut)来确定它们将被应用到哪些对象上。
AOP 的实现方式有很多种,其中比较常见的是使用 Spring AOP 框架,它提供了基于代理机制的 AOP 实现,通过动态代理将切面织入目标对象中实现横切逻辑的调用。
同时,Spring AOP 还支持多种通知类型,如前置通知、后置通知、异常通知、环绕通知等,并提供了可配置的切点表达式语言,方便开发人员灵活地定义切点。
AOP 的主要作用如下:
- 代码复用:将多个模块共同的横切关注点抽象出来,作为切面,然后在需要使用这些关注点的模块中引入相应的切面,从而避免了代码的重复编写。
- 系统解耦:将横切关注点与业务逻辑分离,避免了它们之间的耦合,从而使系统更加易于维护和扩展。
- 简化开发:通过使用 AOP 框架,开发人员可以将横切关注点与业务逻辑的开发分离,从而减少了开发的工作量和复杂度。
- 提高系统性能:AOP 可以在程序运行时动态地织入切面,从而实现对系统的运行时性能进行优化。 综上所述,AOP 是一种非常有用的编程思想,它可以帮助我们实现代码的复用、系统的解耦、开发的简化和性能的优化,是现代软件开发中不可或缺的一部分。
代码展示
框架格式
增强类:
创建接口:
实现接口的方法:
配置核心文件xml:
测试方法:
测试结果: