Sping-AOP:cglib动态代理与JDK动态代理的区别

2024-06-21 06:32

本文主要是介绍Sping-AOP:cglib动态代理与JDK动态代理的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

默认状态下,Spring-AOP默认使用JDK动态代理,当需要代理的对象没有实现任何接口时,才使用cglib动态代理。
下面,将向大家介绍JDK动态代理和Cglib动态代理的使用、两者的区别已经注意事项。

一、JDK动态代理

由于JDK动态代理是基于接口,所以我们先定义一个接口和该接口的实现。

//接口
package com.ghs.aop.proxy;public interface TestService {void testMethod1();void testMethod2();
}//接口的实现类
package com.ghs.aop.proxy.impl;import com.ghs.aop.proxy.TestService;public class TestServiceWithInterface implements TestService{@Overridepublic void testMethod1() {System.out.println("With Interface: I'm the first method!");}@Overridepublic void testMethod2() {System.out.println("With Interface: I'm the second method!");}}

下面,我们定义一个切面。

package com.ghs.aop.proxy;public class ProxyAspect {public void before(){System.out.println("前置通知!");}public void after(){System.out.println("后置通知!");}
}

对该切面进行AOP配置,如下:

<bean id="testServiceWithInterface" class="com.ghs.aop.proxy.impl.TestServiceWithInterface"></bean><bean id="proxyAspect" class="com.ghs.aop.proxy.ProxyAspect"></bean>
<aop:config><aop:aspect ref="proxyAspect"><aop:pointcut expression="execution(* *.testMethod*(..))" id="proxyPointCut"/><aop:before method="before" pointcut-ref="proxyPointCut"/><aop:after method="after" pointcut-ref="proxyPointCut"/></aop:aspect>
</aop:config>

执行我们的测试代码

public class TestProxy {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-proxy.xml");TestService withInterface = (TestService) context.getBean("testServiceWithInterface");withInterface.testMethod1();withInterface.testMethod2();}
}//运行结果如下:
前置通知!
With Interface: I'm the first method!
后置通知!
前置通知!
With Interface: I'm the second method!
后置通知!

我们需要注意下面几点:

  • 下面这句代码,只能将testServiceWithInterface对象强转为TestService,而不能强转为TestServiceWithInterface,因为JDK动态代理是基于接口的。

    TestService withInterface = (TestService) context.getBean("testServiceWithInterface");

二、Cglib动态代理

在上面的例子中,如果需要强制使用cglib进行动态代理,其实只需要改一下aop的配置。

<aop:config>......</aop:config>
改为
<aop:config proxy-target-class="true">......</aop:config>

其实默认情况下proxy-target-class值为false,此时,Spring-AOP默认使用JDK动态代理,当需要代理的对象没有实现任何接口时,才使用cglib动态代理。
当proxy-target-class设置为true时,Spring-AOP对需要代理的对象统一使用cglib动态代理。

在使用cglib动态代理时,需要注意下面几点:

  • 需要引入cglib的jar包,有两种方式,一是引入cglib.jar和asm.jar,二是引入cglib-nodep.jar
  • 对象的final方法无法被拦截

这篇关于Sping-AOP:cglib动态代理与JDK动态代理的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1080456

相关文章

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S

MySQL中VARCHAR和TEXT的区别小结

《MySQL中VARCHAR和TEXT的区别小结》MySQL中VARCHAR和TEXT用于存储字符串,VARCHAR可变长度存储在行内,适合短文本;TEXT存储在溢出页,适合大文本,下面就来具体的了解... 目录一、VARCHAR 和 TEXT 基本介绍1. VARCHAR2. TEXT二、VARCHAR

Java JDK Validation 注解解析与使用方法验证

《JavaJDKValidation注解解析与使用方法验证》JakartaValidation提供了一种声明式、标准化的方式来验证Java对象,与框架无关,可以方便地集成到各种Java应用中,... 目录核心概念1. 主要注解基本约束注解其他常用注解2. 核心接口使用方法1. 基本使用添加依赖 (Maven

Python动态处理文件编码的完整指南

《Python动态处理文件编码的完整指南》在Python文件处理的高级应用中,我们经常会遇到需要动态处理文件编码的场景,本文将深入探讨Python中动态处理文件编码的技术,有需要的小伙伴可以了解下... 目录引言一、理解python的文件编码体系1.1 Python的IO层次结构1.2 编码问题的常见场景二

python中getsizeof和asizeof的区别小结

《python中getsizeof和asizeof的区别小结》本文详细的介绍了getsizeof和asizeof的区别,这两个函数都用于获取对象的内存占用大小,它们来自不同的库,下面就来详细的介绍一下... 目录sys.getsizeof (python 内置)pympler.asizeof.asizeof

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对