当前位置:首页 > CN2资讯 > 正文内容

Spring 静态代理与动态代理spring动态代理

3天前CN2资讯

Spring06: 静态与动态代理

什么是代理

了解代理就要自动什么是代理,代理就是代理你办事的“人”,生活中有许多这样的例子,比如婚介所,中介。

代理有什么好处

可以让代码更加纯粹,不需要在主要业务代码中加入其他附庸的功能

公共部分交给了代理,实现了业务的分工

公共业务发生扩展的时候,方便集中管理

静态代理

静态代理由程序员或代码生成工具生成代理类,编译之后生成Class文件,代理关系在编译期就已经绑定,一个代理关系是一个代理类对应一个基础接口。

角色分析

1、抽象角色:一般使用接口或抽象类
2、真实角色:被代理的角色
3、代理角色:代理真实角色,代理真实角色后,我们会做一些附属操作
4、客户角色:访问代理对象的人

代码实现

1.抽象角色(租房)

package com.znsd.spring.test; public interface Rent { void rentOut(); }

2.真实角色(房东)

package com.znsd.spring.test; public class Host implements Rent{ @Override public void rentOut() { // TODO Auto-generated method stub System.out.println("房东要出租房屋"); } }

3.代理角色(房屋中介)

package com.znsd.spring.test; public class Agency implements Rent{ Host host = new Host(); @Override public void rentOut() { // TODO Auto-generated method stub host.rentOut();         // 房东的额外操作         fee();         contract();         see(); } public void fee() { System.out.println("收佣金"); } public void contract() { System.out.println("签合同"); } public void see() { System.out.println("看房"); } }

4.客户角色(需要租房的人)

package com.znsd.spring.test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; class Dynamic { @Test void test() { Rent rent = new Agency(); rent.rentOut(); } }

测试结果:

动态代理

jdk动态代理

是JDK1.3中引入的特性,核心API是java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。它利用反射机制在运行时生成代理类的字节码,为Java平台在带来了运行时动态扩展对象行为的能力。其代理关系是在程序运行时期确定得。(必须使用接口)

接口

package com.znsd.spring.dynamicProxy; public interface UserService { void add(int id); void delete(int id); void update(int id); void query(int id); }

被代理类

package com.znsd.spring.dynamicProxy; public class UserServiceImpl implements UserService{ private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) {  = name; } @Override public void add(int id) { // TODO Auto-generated method stub System.out.println("增加"); } @Override public void delete(int id) { // TODO Auto-generated method stub System.out.println("删除"); } @Override public void update(int id) { // TODO Auto-generated method stub System.out.println("修改"); } @Override public void query(int id) { // TODO Auto-generated method stub System.out.println("查询"); } }

增强类

package com.znsd.spring.dynamicProxy; public class Extend { public static void log(String msg,int id) { System.out.println(msg+"了id为:"+id+"的用户"); } }

生成被代理类

package com.znsd.spring.dynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyInvocationHandler implements InvocationHandler{ private Object object; public ProxyInvocationHandler() { super(); } public ProxyInvocationHandler(Object object) { super(); this.object = object; } public void setObject(Object object) { this.object = object; } public Object getProxy() { return Proxy.newProxyInstance(this.getClass().getClassLoader(), object.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object rusObject = method.invoke(object, args); Extend.log(method.getName(), (int)args[0]); return rusObject; } }

代理程序控制器

package com.znsd.spring.dynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyInvocationHandler implements InvocationHandler{ private Object object; public ProxyInvocationHandler() { super(); } public ProxyInvocationHandler(Object object) { super(); this.object = object; } public void setObject(Object object) { this.object = object; } public Object getProxy() { // 生成被代理类 return Proxy.newProxyInstance(this.getClass().getClassLoader(), object.getClass().getInterfaces(),  this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object rusObject = method.invoke(object, args); Extend.log(method.getName(), (int)args[0]); return rusObject; } }

使用测试

package com.znsd.spring.dynamicProxy; public class Main { public static void main(String[] args) { ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(new UserServiceImpl()); UserService userService  = (UserService)proxyInvocationHandler.getProxy(); userService.add(1); userService.delete(2); userService.update(3); userService.query(4); } }
cglib动态代理

CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。CGLIB通过继承方式实现代理。

CGLIB动态代理的实现机制是生成目标类的子类,在子类中调用父类的方法从而实现对目标父类方法的增强。

被代理类:

package com.znsd.spring.cglib; public class Tatger { public void save() { System.out.println("正在保存"); } }

代理程序控制类:

package com.znsd.spring.cglib; import java.lang.reflect.Method; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { // TODO Auto-generated method stub MyLog.befor(); Object obj = arg3.invokeSuper(arg0, arg2); MyLog.end(); return obj; } }

增强类:

package com.znsd.spring.cglib; import java.io.Console; public class MyLog { public static void befor() { System.out.println("前置Log"); } public static void end() { System.out.println("后置Log"); } }

生成代理类:

package com.znsd.spring.cglib; import org.springframework.cglib.proxy.Enhancer; public class CglibProxy { public static Object getProxy(Class clazz) {  // 创建动态代理增强类         Enhancer enhancer = new Enhancer();         // 设置类加载器         enhancer.setClassLoader(clazz.getClassLoader());         // 设置被代理类         enhancer.setSuperclass(clazz);         // 设置方法拦截器         enhancer.setCallback(new MyMethodInterceptor());         return enhancer.create(); } }

测试:

package com.znsd.spring.cglib; import static org.junit.jupiter.api.Assertions.*; class Test { @org.junit.jupiter.api.Test void test() { Tatger tatger = (Tatger) CglibProxy.getProxy(Tatger.class); tatger.save(); } }
两种动态代理的区别

1、Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理

2、 Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理

什么时候用cglib什么时候用jdk动态代理?

1、目标对象生成了接口 默认用JDK动态代理

2、如果目标对象使用了接口,可以强制使用cglib

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

JDK动态代理和cglib字节码生成的区别?

1、JDK动态代理只能对实现了接口的类生成代理,而不能针对类

2、Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法的增强,但是因为采用的是继承,所以该类或方法最好不要生成final,对于final类或方法,是无法继承的

Cglib比JDK快?

1、cglib底层是ASM字节码生成框架,但是字节码技术生成代理类,在JDL1.6之前比使用java反射的效率要高

2、在jdk6之后逐步对JDK动态代理进行了优化,在调用次数比较少时效率高于cglib代理效率

3、只有在大量调用的时候cglib的效率高,但是在1.8的时候JDK的效率已高于cglib

4、Cglib不能对声明final的方法进行代理,因为cglib是动态生成代理对象,final关键字修饰的类不可变只能被引用不能被修改

Spring如何选择是用JDK还是cglib?

1、当bean实现接口时,会用JDK代理模式

2、当bean没有实现接口,用cglib实现

3、可以强制使用cglib(在spring配置中加入<aop:aspectj-autoproxy proxyt-target-class=”true”/

    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/23980.html

    分享给朋友:

    “Spring 静态代理与动态代理spring动态代理” 的相关文章

    中国电信CN2宽带套餐怎么样?高速稳定的上网体验就在身边

    在这个数字化时代,优质的宽带网络已经成为每个家庭和企业不可或缺的一部分。而中国电信CN2宽带套餐,正是为满足用户对高速、稳定、智能的网络需求而推出的全新解决方案。无论是日常浏览、在线办公,还是高清视频娱乐,CN2宽带都能为用户提供卓越的上网体验。中国电信CN2宽带套餐的最大亮点在于其高速稳定的特点。...

    2024年如何获取免费VPS服务:开发者的最佳选择

    在解释什么是免费VPS之前,我想先来聊聊“VPS”这个概念。虚拟专用服务器(VPS)可以理解为一种在服务器上创建多个虚拟环境的技术。这些环境如同独立的服务器,用户可以在上面进行程序的开发和测试。而“免费VPS”则意味着用户可以在一定的限度内,无需付费地使用这些虚拟环境。对于初创公司或个人开发者而言,...

    甲骨文云注册:详细流程与免费试用攻略

    甲骨文云注册概述 甲骨文云介绍和服务特点 我对甲骨文云的首要印象是它独一无二的服务。甲骨文云不仅提供高性能的VPS服务器,还给予用户一个轻松的起步体验。其主要服务包括两台配置为1核1G内存、50G硬盘和10T流量的AMD VPS,还有一台配置为4核24G内存、100G硬盘、10T流量的ARM VPS...

    PVE环境下是否需要设置路由器?轻松拷贝文件的最佳实践

    PVE概述 Proxmox Virtual Environment(PVE)是一个开源的虚拟化管理平台,集成了KVM和LXC技术。简单来说,它允许用户在一台物理服务器上创建和管理多个虚拟机和容器。使用PVE让你轻松地部署、监控和管理自己的虚拟化环境,不论是用于开发、测试,还是生产环境。PVE提供了一...

    VPS商家全攻略:选择适合你的虚拟专用服务器

    VPS商家概述 在数字化时代,VPS(虚拟专用服务器)服务逐渐成为企业和个人用户的重要选择。VPS不仅为用户提供了灵活性,而且在性能、控制权和安全性上都优于传统的共享主机。这使它成为许多需要独立环境来运行网站或应用程序的用户的理想解决方案。 选择VPS的用户通常追求更高的稳定性和可靠性。相比于共享主...

    Zenlayer如何优化企业全球网络连接与数字化转型

    在当今数字化时代,企业对全球网络连接的需求呈现出爆炸式增长。Zenlayer作为一家基于SDN的全球网络及服务提供商,恰如其分地填补了这一市场空白。总部位于洛杉矶的Zenlayer,不仅连接着企业和用户与云端,还通过其高度灵活的裸机云、云连接以及边缘计算服务,帮助企业迅速部署和管理全球IT资源。我认...