代理模式

代理模式:

  • 静态代理
  • 动态代理
    学习aop之前,要先了解代理模式

静态代理

  • 抽象角色:一般使用接口或者抽象类来实现
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色;代理真实角色后,一般会做一些附属操作。
  • 客户:使用代理角色来进行一些操作。

代码实现

Rent.java 即抽象角色

//抽象角色:租房
public interface Rent{
public void rent();
}

Host.java即真实角色

//真实角色: 房东,房东要出租房子
public class Host implements Rent{
public void rent() {
System.out.println("房屋出租");
}
}

Proxy.java 即代理角色

//代理角色:中介
public class Proxy implements Rent { private Host host;
public Proxy() { }
public Proxy(Host host) {
this.host = host;
} //租房
public void rent(){
seeHouse();
host.rent();
fare();
}
//看房
public void seeHouse(){
System.out.println("带房客看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
}

Client.java即客户

//客户类,一般客户都会去找代理!
public class Client {
public static void main(String[] args) {
//房东要租房
Host host = new Host();
//中介帮助房东
Proxy proxy = new Proxy(host); //你去找中介!
proxy.rent();
}
}

分析:在这个过程中,你直接接触的就是中介,就如同显示生活中的样子,你看不到房东,但是你依旧租到了房东的房子通过代理,这就是所谓的代理模式,程序源自于生活,生活中处处都能抽象出程序!!!

静态代理的好处:

  • 可以使得我们的真实角色更加纯粹,不再去关注一些公共的事情。
  • 公共的业务由代理来完成,实现了业务的分工。
  • 公共业务发生拓展时变得更加集中和方便

静态代理的缺点:

  • 类多了,多了代理类,工作量变大了,开发效率降低。

动态代理

  • 动态代理的角色和静态代理一样
  • 动态代理的代理类是动态生成的,静态代理的代理类是我们自己提前写好的
  • 动态代理分为两类:一类是基于接口动态代理,一类是基于类的动态代理
    - 基于接口的动态代理————JDK动态代理
    - 基于类的动态代理 ————cglib
    - 现在用的比较多的是Javasist来生成动态代理

JDK的动态代理需要了解两个类

核心:InvocationHandler 和 Proxy
【InvocationHandler:调用处理程序】

Object invoke(Object proxy, 方法 method, Object[] args);
//参数
//proxy - 调用该方法的代理实例
//method -所述方法对应于调用代理实例上的接口方法的实例。方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
//args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。

【Proxy : 代理】

Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类

每个代理实例都有一个关联的调用处理程序对象,它实现了接口InvocationHandler。

**public static Object newProxyInstance(ClassLoader loader,类<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序

参数:
loader - 类加载器来定义代理类
interfaces - 代理类实现的接口列表
h - 调度方法调用的调用处理函数

//生成代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}

代码实现

抽象角色和真实角色和之前的一样!
Rent.java即抽象角色

//抽象角色:租房
public interface Rent {
public void rent();
}

Host.java即真实角色

//真实角色: 房东,房东要出租房子
public class Host implements Rent{
public void rent() {
System.out.println("房屋出租");
}
}

ProxyInvocationHandler. java 即代理角色

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);
} // proxy : 代理类 method : 代理类的调用处理程序的方法对象.
// 处理代理实例上的方法调用并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
//核心:本质利用反射实现!
Object result = method.invoke(rent, args);
fare();
return result;
} //看房
public void seeHouse(){
System.out.println("带房客看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
} }

Client . java

//租客
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();
} }

编写一个通用的动态代理实现的类!所有的代理对象设置为Object即可!

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);
} // proxy : 代理类
// method : 代理类的调用处理程序的方法对象.
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(target, args);
return result;
} public void log(String methodName){
System.out.println("执行了"+methodName+"方法");
} }

动态代理的好处

静态代理有的它都有,静态代理没有的,它也有!

  • 可以使得我们的真实角色更加纯粹,不再去关注一些公共的事情。
  • 公共的业务由代理来完成,实现了业务的分工。
  • 公共业务发生扩展时变得更加集中和方便
  • 一个动态代理,一般代理某一类业务。
  • 一个动态代理可以代理多个类,代理的是接口。

Spring——静态/动态代理模式的更多相关文章

  1. 正向代理和反向代理和spring的动态代理模式有几种?默认是那种?如何切换?

    spring的动态代理模式有几种?默认是那种?如何切换? spring的动态的代理模式有两种 JDK动态代理,基于接口(默认代理模式),CGLIB动态代理(若要使用需要进行配置) JDK动态代理是由j ...

  2. Java静态代理与动态代理模式的实现

    前言:    在现实生活中,考虑以下的场景:小王打算要去租房,他相中了一个房子,准备去找房东洽谈相关事宜.但是房东他很忙,平时上班没时间,总找不到时间去找他,他也没办法.后来,房东想了一个办法,他找到 ...

  3. Spring代理模式(jdk动态代理模式)

    有动态代理和静态代理: 静态代理就是普通的Java继承调用方法. Spring有俩种动态代理模式:jdk动态代理模式 和 CGLIB动态代理 jdk动态代理模式: 代码实现: 房东出租房子的方法(继承 ...

  4. spring AOP 动态代理和静态代理以及事务

    AOP(Aspect Oriented Programming),即面向切面编程 AOP技术,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装 ...

  5. Spring代理模式(CGLIB动态代理模式)

    jdk动态代理和CGLIB动态代理 没什么太大的区别,CGLIB动态代理不需要接口,但是需要导入jar包. 房东出租房子的方法: package com.bjsxt.proxy2; public cl ...

  6. Hibernate 延迟加载的代理模式 和 Spring AOP的代理模式

    Hibernate 延迟加载的代理模式 和 Spring AOP的代理模式 主题 概念 Hibernate 延迟加载的代理模式 Spring AOP的代理模式 区别和联系 静态代理和动态代理 概念 代 ...

  7. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

  8. Java-马士兵动态代理模式

    Java-马士兵动态代理模式 模拟jdk的动态代理的实现原理, 这些东西没有必要写出来,写项目的时候一般用不上,主要是为了面试和理解原理: java动态代理有什么作用 作用非常大,在很多底层框架中都会 ...

  9. spring设计模式_代理模式

    代理模式应该是Spring核心设计模式之一了 先说下代理模式特性: 1.有代理人和被代理人 2.对于被代理的人来说,这件事情是一定要做的,但是我又不想做,所有就找代理人来做. 3.需要获取到被代理人的 ...

  10. 设计模式之jdk动态代理模式、责任链模式-java实现

    设计模式之JDK动态代理模式.责任链模式 需求场景 当我们的代码中的类随着业务量的增大而不断增大仿佛没有尽头时,我们可以考虑使用动态代理设计模式,代理类的代码量被固定下来,不会随着业务量的增大而增大. ...

随机推荐

  1. Pikachu漏洞靶场 XSS(跨站脚本攻击)

    XSS 关于xss的我也是一知半解,所以只放出payload来. 反射型xss(get) 修改maxlength属性之后提交如下内容: <script>alert(/xss/);</ ...

  2. MongoDB的CRUD操作(入门)

    MongoDB的简单介绍: 1:MongoDB是什么? mongodb是非关系数据库 但是是非关系数据库当中功能最丰富,最像关系数据库的 MongoDB是一个基于分布式文件存储的数据库. 由C++语言 ...

  3. 面试官:单例Bean一定不安全吗?实际工作中如何处理此问题?

    默认情况下,Spring Boot 中的 Bean 是非线程安全的.这是因为,默认情况下 Bean 的作用域是单例模式,那么此时,所有的请求都会共享同一个 Bean 实例,这意味着这个 Bean 实例 ...

  4. 文心一言 VS 讯飞星火 VS chatgpt (127)-- 算法导论11.2 2题

    二.用go语言,位向量(bit vector)是一个仅包含0和1的数组.长度为m的位向量所占空间要比包含m个指针的数组少得多.请说明如何用一个位向量来表示一个包含不同元素(无卫星数据)的动态集合.字典 ...

  5. 23、Flutter AppBar TabBar TabBarView

    AppBar自定义顶部按钮图标.颜色 class MyHomePage extends StatelessWidget { const MyHomePage({super.key}); @overri ...

  6. Python实用技巧:将 Excel转为PDF

    将Excel文件转换为PDF可以方便储存表格数据,此外在打印或共享文档时也能确保表格样式布局等在不同设备和操作系统上保持一致.今天给大家分享一个使用第三方Python库Spire.XLS for Py ...

  7. 拥抱Serverless释放生产力,探索华为云Serverless车联网最佳实践

    华为云Serverless车联网场景解决方案,以FunctionGraph为核心的Serverless化组合方案,使用FunctionGraph.OBS.DIS等技术,可以实现架构的灵活扩展,在出行高 ...

  8. 2天完成17TB数据量迁移,华为云数据库是如何做的?

    摘要:童年时候,我们会对着墙上挂着的中国地图,来认识一处处山川河流和城市人文.如今,数字化时代下,传统的地图已经不能满足人们的需求,如何获取各种丰富的地理内容和实时动态信息成为现代人普遍的地理信息诉求 ...

  9. 30亿参数,华为云发布全球最大预训练模型,开启工业化AI开发新模式

    摘要: 4月25日,华为云发布盘古系列超大规模预训练模型,包括30亿参数的全球最大视觉(CV)预训练模型,以及与循环智能.鹏城实验室联合开发的千亿参数.40TB训练数据的全球最大中文语言(NLP)预训 ...

  10. 传统到敏捷的转型中,谁更适合做Scrum Master?

    摘要:本文主要讲述的是从传统到敏捷Scrum团队转型中,对Scrum Master这一角色的分析. 本文分享自华为云社区<传统到敏捷的转型中,谁更适合做Scrum Master?>,作者: ...