当前位置:网站首页>动态代理学习
动态代理学习
2022-08-11 06:46:00 【LiuJia111222333】
动态代理和静态代理角色一样 动态代理的代理类是动态生成的,不是我们直接写好的 动态代理分为两大类:基本接口的动态代理,基本类的动态代理
三种方法实现动态代理:
- 基于接口---jdk动态代理
- 基于类:cglib
- java字节码实现:javassit
需要了解两个类:Proxy(代理类),InvocationHandler (调用处理程序)
InvocationHandler
InvocationHandler
是代理实例的调用处理程序 实现的接口。
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke
方法。
invoke(Object proxy, Method method, Object[] args)
参数解析:
proxy
- 调用该方法的代理实例
method
-Method
对应于代理实例上调用的接口方法的实例。对象的声明类Method
将是声明方法的接口,它可能是代理类继承方法的代理接口的超接口。
args
- 包含在代理实例上的方法调用中传递的参数值的对象数组,或者null
如果接口方法不接受任何参数。原始类型的参数被包装在适当的原始包装类的实例中,例如 java.lang.Integer
or java.lang.Boolean
。
Proxy创建静态的代理类
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class<?>[] { Foo.class },
handler);
参数解析:
loader
- 定义代理类的类加载器
interfaces
- 代理类要实现的接口列表
h
- 将方法调用分派到的调用处理程序
学习案例1:
Rent接口
//租房接口
public interface Rent {
public void rent(); //租房
}
Host房东类
//房东实现租房接口,代表他要租房了
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东需要出租房子了!");
}
}
ProxyInvocationHandler 处理程序类
//等我们会用这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
//创建被代理的接口
private Rent rent;
public void setRent(Rent rent){
this.rent = rent;
}
//生成得到的代理类
public Object getProxy(){
//创建个代理类
return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果,当执行接口是,系统会默认执行invoke处理程序
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行房东出租房子
Object result = method.invoke(rent, args);
seeHouse();
SignContract();
return result;
}
//处理其他业务
public void seeHouse(){
System.out.println("中介带看房子");
}
//处理其他业务
public void SignContract(){
System.out.println("中介签合同");
}
}
主类
public class Client {
public static void main(String[] args) {
//真实角色是房东,他需要找代理给她出租房子
Host host = new Host();
//代理角色暂时没有,于是需要我们创建
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setRent(host); //设置房东需要代理
//已经创建房东要租房子的代理类了。
Rent proxy = (Rent) pih.getProxy();
//执行租房
proxy.rent();
}
}
学习案例2 -- 通用动态代理:
UserService接口
public interface UserService {
void add();
void update();
void delete();
void select();
}
UserServiceImpl实现类:
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("使用了add方法 ");
}
@Override
public void update() {
System.out.println("使用了update方法 ");
}
@Override
public void delete() {
System.out.println("使用了delete方法 ");
}
@Override
public void select() {
System.out.println("使用了select方法 ");
}
}
ProxyInvocationHandler类:
//创建个万能动态代理
//等我们会用这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
//创建被代理的接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//生成得到的代理类
public Object getProxy() {
//创建个代理类
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
//处理代理实例,并返回结果,当执行接口是,系统会默认执行invoke处理程序
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态的获取该方法的名字
System.out.println("debug提示:"+"使用了"+method.getName()+"方法");
//执行房东出租房子
Object result = method.invoke(target, args);
return result;
}
}
主类:
public class Client {
public static void main(String[] args) {
//创建一个真实角色
UserService userService = new UserServiceImpl();
//生成一个代理绝色
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setTarget(userService);
//创建代理类
UserService proxy = (UserService) pih.getProxy();
proxy.delete();//执行删除方法
}
}
边栏推荐
- 机器学习总结(二)
- Daily sql - judgment + aggregation
- 《猪猪1984》NFT 作品集将上线 The Sandbox 市场平台
- Douyin get douyin share password url API return value description
- 易观分析联合中小银行联盟发布海南数字经济指数,敬请期待!
- redis操作
- Redis源码:Redis源码怎么查看、Redis源码查看顺序、Redis外部数据结构到Redis内部数据结构查看源码顺序
- Tidb二进制集群搭建
- Discourse 的关闭主题(Close Topic )和重新开放主题
- TF中使用softmax函数;
猜你喜欢
When MySQL uses GROUP BY to group the query, the SELECT query field contains non-grouping fields
如何选择专业、安全、高性能的远程控制软件
从何跟踪伦敦金最新行情走势?
Daily sql--statistics the total salary of employees in the past three months (excluding the latest month)
常见激活函数及其导数
NFT 的价值从何而来
【软件测试】(北京)字节跳动科技有限公司二面笔试题
Resolved EROR 1064 (42000): You have an error in. your SOL syntax. check the manual that corresponds to yo
Tf中的平方,多次方,开方计算
一张图了解JVM八大原子操作
随机推荐
第一个C函数:如何实现板级初始化?
Unity底层是如何处理C#的
TF通过feature与label生成(特征,标签)集合,tf.data.Dataset.from_tensor_slices
STM32CUBEIDE(11)----输出PWM及修改PWM频率与占空比
【推荐系统】:协同过滤和基于内容过滤概述
Taobao API interface reference
Strongly recommend an easy-to-use API interface
prometheus学习4Grafana监控mysql&blackbox了解
tf中自减操作;tf.assign_sub()
《猪猪1984》NFT 作品集将上线 The Sandbox 市场平台
Trill keyword search goods - API
break pad源码编译--参考大佬博客的总结
1003 我要通过 (20 分)
接口测试的基础流程和用例设计方法你知道吗?
基于FPGA的FIR滤波器的实现(5)— 并行结构FIR滤波器的FPGA代码实现
语音信号处理:预处理【预加重、分帧、加窗】
LeetCode brushing series -- 46. Full arrangement
博途PLC 1200/1500PLC ModbusTcp通信梯形图优化汇总(多服务器多从站轮询)
Multiscale communication in cortical-cortical networks
MindManager2022全新正式免费思维导图更新