您的位置:首页 > 科技 > 能源 > 长沙公司网络推广_小程序短剧_百度推广全国代理商排名_百度站长工具平台登录

长沙公司网络推广_小程序短剧_百度推广全国代理商排名_百度站长工具平台登录

2024/9/21 20:18:40 来源:https://blog.csdn.net/2301_76207358/article/details/142356623  浏览:    关键词:长沙公司网络推广_小程序短剧_百度推广全国代理商排名_百度站长工具平台登录
长沙公司网络推广_小程序短剧_百度推广全国代理商排名_百度站长工具平台登录

一、代理模式

代理模式:给某一个对象提供一个代理,并由代理对象来控制对真实对象的访问。代理模式是一种结构型设计模式。
代理模式角色分为 3种:
Subject(抽象主题角色):定义代理类和真实主题的公共对外方法,通常被设计成接口;
RealSubject(真实主题角色):真正实现业务逻辑的类;
Proxy(代理主题角色):用来代理和封装真实主题;
代理模式的结构比较简单,其核心是代理类,为了让客户端能够一致性地对待真实对象和代理对象,在代理模式中引入了抽象层。

如果根据字节码的创建时机来分类,可以分为静态代理动态代理:
所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和真实主题角色的关系在运
行前就确定了。
而动态代理的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以在运行前并不存在代
理类的字节码文件 

 1.1静态代理

静态代理的工作原理如下:

  • 定义一个接口(或抽象类)作为目标接口,目标对象实现这个接口。
  • 创建一个代理类,实现目标接口,并持有目标对象的引用。
  • 在代理类中重写目标接口的方法,在方法调用前后执行需要的额外操作。
  • 客户端使用代理对象来访问目标对象。

代码例子: 

静态代理通过 UserServiceProxy实现,代理类同时也需要实现UserService 接口。

UserService:

public interface UserService {public void select();	public void update();
}

UserServiceImpl: 

//RealSubject 真实主题(真正的业务类)
public class UserServiceImpl implements UserService{@Overridepublic void select() {System.out.println("查询selectById");		}@Overridepublic void update() {System.out.println("更新update");}}

UserServiceProxy:

//代理
public class UserServiceProxy implements UserService{//包含Subject真实的主题private UserServiceImpl realUserService =new UserServiceImpl();@Overridepublic void select() {long begin=System.currentTimeMillis();	//调用真正的业务逻辑realUserService.select();long end=System.currentTimeMillis();System.out.println("select()执行耗时"+(end-begin)+"毫秒!");}@Overridepublic void update() {realUserService.update();		}
}

 测试:

public class Test {public static void main(String[] args) {UserServiceProxy userServiceProxy=new UserServiceProxy();userServiceProxy.select();}
}

通过静态代理,我们达到了功能增强的目的,而且没有侵入原代码,这是静态代理的一个优点。
虽然静态代理实现简单,且不侵入原代码,但是,当场景稍微复杂一些的时候,静态代理的缺点也
会暴露出来。
当需要代理多个类的时候,由于代理对象要实现与目标对象一致的接口,有两种方式:

  • 只维护一个代理类,由这个代理类实现多个接口,但是这样就导致代理类过于庞大
  • 新建多个代理类,每个目标对象对应一个代理类,但是这样会产生过多的代理类

当接口需要增加、删除、修改方法的时候,目标对象与代理类都要同时修改,不易维护

静态代理的特点:

需要手动编写代理类,工作量较大。

目标对象必须实现接口。

代理类和目标类的关系在编译时就确定了,无法动态改变

1.2动态代理

Java 中两种常见的动态代理方式: JDK 原生动态代理和 CGLIB 动态代理(第三方开源类
库)。

动态代理的工作原理如下:

定义一个接口,作为目标接口。

创建一个InvocationHandler接口的实现类,该类负责处理方法调用并执行额外的操作。

使用Proxy类的静态方法newProxyInstance()生成代理对象,同时指定目标对象和InvocationHandler。

客户端使用代理对象来访问目标对象的方法。

 代码例子如下:

OrderService :

public interface OrderService {public void create(double money,int uid);}

OrderServiceImpl: 

public class OrderServiceImpl implements OrderService {@Overridepublic void create(double money, int uid) {System.out.println("订单金额:¥"+money);System.out.println("订单id:"+uid);}
}

PerformanceInvocationHandler: 

//用于监测方法执行性能的Handler执行器
public class PerformanceInvocationHandler implements InvocationHandler {private Object real;public PerformanceInvocationHandler(Object real) {this.real=real;}	@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {long begin=System.currentTimeMillis();//真实业务对象当前的执行方法(基于反射的方式)Object returnValue=method.invoke(real, args);long end=System.currentTimeMillis();System.out.println("方式执行耗时"+(end-begin)+"毫秒!");return returnValue;}
}

Test:

public class Test {public static void main(String[] args) {//真实主题对象OrderServiceImpl realOrderService=new OrderServiceImpl();//获取类加载器ClassLoader classLoader=realOrderService.getClass().getClassLoader();//接口列表Class[] interfaces=realOrderService.getClass().getInterfaces();//创建InvocationHandler对象(动态代理的执行逻辑)PerformanceInvocationHandler p=new PerformanceInvocationHandler(realOrderService);//创建一个代理对象(动态代理对象)OrderService orderServiceProxy=(OrderService)Proxy.newProxyInstance(classLoader, interfaces, p);//调用方法orderServiceProxy.create(1345, 0001);		};
}

动态代理的特点:

不需要手动编写代理类,代理对象在运行时动态生成。

目标对象可以不实现接口,只需定义目标对象的共同接口。

代理对象和目标对象的关系在运行时确定,可以动态改变。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com