Spring的两种动态代理:Jdk和Cglib 的区别和实现

Spring的两种动态代理:Jdk和Cglib 的区别和实现

一、原理区别:

java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP

3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

如何强制使用CGLIB实现AOP?
(1)添加CGLIB库,SPRING_HOME/cglib/*.jar
(2)在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>

JDK动态代理和CGLIB字节码生成的区别?
(1)JDK动态代理只能对实现了接口的类生成代理,而不能针对类
(2)CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
因为是继承,所以该类或方法最好不要声明成final

二、代码实现

用户管理接口

package com.lf.shejimoshi.proxy.entity;
//用户管理接口
public interface UserManager {//新增用户抽象方法void addUser(String userName,String password);//删除用户抽象方法void delUser(String userName);}

用户管理接口实现类

package com.lf.shejimoshi.proxy.entity;
//用户管理实现类,实现用户管理接口
public class UserManagerImpl implements UserManager{//重写新增用户方法@Overridepublic void addUser(String userName, String password) {System.out.println("调用了新增的方法!");System.out.println("传入参数为 userName: "+userName+" password: "+password);}//重写删除用户方法@Overridepublic void delUser(String userName) {System.out.println("调用了删除的方法!");System.out.println("传入参数为 userName: "+userName);}}

JDK动态代理

package com.lf.shejimoshi.proxy.jdk;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;import com.lf.shejimoshi.proxy.entity.UserManager;
import com.lf.shejimoshi.proxy.entity.UserManagerImpl;
//JDK动态代理实现InvocationHandler接口
public class JdkProxy implements InvocationHandler {private Object target ;//需要代理的目标对象@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("JDK动态代理,监听开始!");Object result = method.invoke(target, args);System.out.println("JDK动态代理,监听结束!");return result;}//定义获取代理对象方法private Object getJDKProxy(Object targetObject){//为目标对象target赋值this.target = targetObject;//JDK动态代理只能针对实现了接口的类进行代理,newProxyInstance 函数所需参数就可看出return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);}public static void main(String[] args) {JdkProxy jdkProxy = new JdkProxy();//实例化JDKProxy对象UserManager user = (UserManager) jdkProxy.getJDKProxy(new UserManagerImpl());//获取代理对象user.addUser("admin", "123123");//执行新增方法}}

JDK动态代理运行结果

img

Cglib动态代理(需要导入两个jar包,asm-5.2.jar,cglib-3.2.5.jar。版本自行选择)

package com.lf.shejimoshi.proxy.cglib;import java.lang.reflect.Method;import com.lf.shejimoshi.proxy.entity.UserManager;
import com.lf.shejimoshi.proxy.entity.UserManagerImpl;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;//Cglib动态代理,实现MethodInterceptor接口
public class CglibProxy implements MethodInterceptor {private Object target;//需要代理的目标对象//重写拦截方法@Overridepublic Object intercept(Object obj, Method method, Object[] arr, MethodProxy proxy) throws Throwable {System.out.println("Cglib动态代理,监听开始!");Object invoke = method.invoke(target, arr);//方法执行,参数:target 目标对象 arr参数数组System.out.println("Cglib动态代理,监听结束!");return invoke;}//定义获取代理对象方法public Object getCglibProxy(Object objectTarget){//为目标对象target赋值this.target = objectTarget;Enhancer enhancer = new Enhancer();//设置父类,因为Cglib是针对指定的类生成一个子类,所以需要指定父类enhancer.setSuperclass(objectTarget.getClass());enhancer.setCallback(this);// 设置回调 Object result = enhancer.create();//创建并返回代理对象return result;}public static void main(String[] args) {CglibProxy cglib = new CglibProxy();//实例化CglibProxy对象UserManager user =  (UserManager) cglib.getCglibProxy(new UserManagerImpl());//获取代理对象user.delUser("admin");//执行删除方法}}

Cglib动态代理运行结果

img

有什么问题可以留言讨论!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556578.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

red6.4 mysql_rhel6.4 yum本地yum源配置

rhel6.4 yum本地yum源配置 在安装rpm包时&#xff0c;总是会碰到关联的包&#xff0c;在安装过程中带来很多麻烦&#xff0c;配置yum源&#xff0c;自关联包安装&#xff0c;简单省事。配置步骤&#xff1a;1&#xff1a;mount -o loop 挂载镜像盘2&#xff1a;编辑rhel…

python怎么判断输入的是不是数字_如何在PYTHON里判断字符串是否为数字

1 打开JUPYTER NOTEBOOK&#xff0c;新建一个空白的PY文档。2 str1 "888" print(str1.isdecimal()) print(str1.isdigit()) print(str1.isnumeric()) 这是正常的整数&#xff0c;三种方法都是可以判断。3 str2 "二" print(str2.isdecimal()) print(str2.…

在springBoot中使用Mapper类问题_@Mapper_@MapperScan_xml文件跟mapper分开_xml文件跟mapper在同一个目录下

文章目录背景xml文件跟mapper分开application.properties方式一&#xff1a; 主程序中MapperScan方式二&#xff1a; 每个接口添加Mapper注意点xml文件跟mapper在同一个目录下SpringBoot中关于Mapper 和 Repository 的一些疑问1. Mapper2. Repository3. MapperScan(“com.xxx.x…

上海交大python答案_上海交通大学python期末考试样题加解析

上海交通大学python期末考试样题加解析 一、选择题: 将唯一正确的选项写在题前括号中.每题2 分. 【 】(1) 本课程的目标定位是什么? [A] 学习Python 语言 [B] 学习计算机的工作原理 [C] 学习各种算法 [D] 学习用计算机解决问题 【 】(2) 下列哪个标识符是合法的? [A] var-nam…

hbase1.1.1 连接集群_Hadoop2.7.1+Hbase1.1.2集群环境搭建(10) hadoop hbase kerberos

1.hadoop安全机制历史在Hadoop1.0.0或者CDH3 版本之前&#xff0c; hadoop并不存在安全认证一说。默认集群内所有的节点都是可靠的&#xff0c;值得信赖的。用户与HDFS或者M/R进行交互时并不需要进行验证。导致存在恶意用户伪装成真正的用户或者服务器入侵到hadoop集群上&#…

SSM框架中mapper和mapping.xml文件在同一个包下需要的配置

前言 当我们在开发过程中&#xff0c;由于maven项目本身的限制&#xff0c;我们不能直接把我们的mapper.xml文件和对应mapper.java接口文件放到一起&#xff0c;也就是不能直接放在java包中&#xff0c;如图&#xff1a; 因为maven项目在构建打包时&#xff0c;会从src/main…

mysql配置文件简易代码_MySQL配置文件my.cnf 例子最详细翻译

转的MySQL配置文件my.cnf 例子最详细翻译,可以保存做笔记用。#BEGIN CONFIG INFO#DESCR: 4GB RAM, 只使用InnoDB, ACID, 少量的连接, 队列负载大#TYPE: SYSTEM#END CONFIG INFO## 此mysql配置文件例子针对4G内存。# 主要使用INNODB#处理复杂队列并且连接数量较少的mysql服务器#…

Spring+Mybatis使用MapperScannerConfigurer简化配置__MapperScannerConfigurer的作用

SpringMybatis使用MapperScannerConfigurer简化配置 MyBatis的一大亮点就是可以不用DAO层的实现类&#xff0c;而我们知道service层调dao层 如果没有实现类&#xff0c;Spring如何为Service注入DAO的实例呢&#xff1f; 比如 现在有一个dao层的bookmapper和配置mybatis的xm…

python的property用法_在python中property怎样使用-百度经验

在python中property可以使类中的方法变为类中的属性一样来使用&#xff0c;使得类中的属性值不易暴露&#xff0c;更加安全&#xff0c;那么在python中property怎样使用呢&#xff1f;下面小编就带大家来看看详细的教程&#xff01;工具/原料 python的版本&#xff1a;python 3…

Spring AOP 实现原理

什么是AOP AOP&#xff08;Aspect-OrientedProgramming&#xff0c;面向方面编程&#xff09;&#xff0c;可以说是OOP&#xff08;Object-Oriented Programing&#xff0c;面向对象编程&#xff09;的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构&…

java string类的方法_Java-String类的常用方法总结

一、String类String类在java.lang包中&#xff0c;java使用String类创建一个字符串变量&#xff0c;字符串变量属于对象。java把String类声明的final类&#xff0c;不能有类。String类对象创建后不能修改&#xff0c;由0或多个字符组成&#xff0c;包含在一对双引号之间二、Str…

python爬虫入门实战---------一周天气预报爬取_Python爬虫入门实战--------一周天气预报爬取【转载】【没有分析...

Python爬虫入门实战--------一周天气预报爬取【转载】【没有分析 Python爬虫入门实战--------一周天气预报爬取【转载】【没有分析】 来源&#xff1a;https://blog.csdn.net/qq_40705355/article/details/83856960七天天气来源&#xff1a;http://www.weather.com.cn/weather/…

Spring IOC原理总结

Spring容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息&#xff0c;并在Spring容器中生成一份相应的Bean配置注册表&#xff0c;然后根据这张注册表实例化Bean&#xff0c;装配好Bean之间的依赖关系&#xff0c;为上层应用提供准备就绪的运行环境。 Bean缓存池&…

Linux开发工具——gcc篇

gcc的使用 文章目录 gcc的使用 历史遗留问题&#xff08;普通用户sudo&#xff09; gcc编译过程 预处理&#xff08;进行宏替换&#xff09; 编译&#xff08;生成汇编&#xff09; 汇编&#xff08;生成机器可识别代码&#xff09; 链接&#xff08;生成可执行文件或库文件&a…

Spring中ioc的实现原理

学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念&#xff0c;对于初学Spring的人来说&#xff0c;总觉得IoC 、DI这两个概念是模糊不清的&#xff0c;是很难理解的&#xff0c;今天和大家分享网上的一些技术大牛们对Spring框架的IOC的理解以及…

如何将一个向量投影到一个平面上_CameraLidar投影:2D3D导航

点击上方“AI小白学视觉”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达图1.图像上的激光雷达点激光雷达和照相机是用于感知和理解场景的两个基本传感器。他们建立周边环境模型、提供检测和确定其他对象位置的方法&#xff0c;从而为机器人提…

JAVA中和、||和|的区别?

问题一&#xff1a;JAVA中&&和&、||和|&#xff08;短路与和逻辑与、短路或和逻辑或&#xff09;的区别&#xff1f; 首先名称是不同的 逻辑运算符&#xff1a;&#xff06;&#xff06;逻辑与  &#xff5c;&#xff5c;逻辑或  它们都是逻辑运算符 位运算…

pppoe拨号的外网ip无法ping通_【思唯网络学院】 五大网络概念:IP地址、子网掩码、网关、DHCP服务和PPPoE拨号...

5G技术的更新&#xff0c;推动了新一代的网络通信发展&#xff0c;家庭宽带上网也从最初的十几K的速度&#xff0c;提升到了现在动则上百上千兆的速度&#xff0c;很多有部署了家庭NAS的用户&#xff0c;甚至都已经更新到了10G级别的内部局域网了。在这个信息互联的时代&#x…

MySQL数据库的数据类型以及取值范围详解

主要包括以下五大类&#xff1a; 整数类型&#xff1a;BIT、BOOL、TINY INT、SMALL INT、MEDIUM INT、 INT、 BIG INT 浮点数类型&#xff1a;FLOAT、DOUBLE、DECIMAL 字符串类型&#xff1a;CHAR、VARCHAR、TINY TEXT、TEXT、MEDIUM TEXT、LONGTEXT、TINY BLOB、BLOB、MEDI…

flex布局_flex布局的 flex(felx-grow、flex-shrink、flex-basis)详解

flex布局中的flex-grow,flex-shrink,flex-basis接上篇文章&#xff0c;1. flex-grow属性flex-grow定义剩余空间的分成。默认为0&#xff0c;即如果存在剩余空间&#xff0c;也不放大。如何理解这里的剩余空间呢&#xff0c;用例子来说明吧。默认的情况(flex-grow:0)在浏览器下是…