spring之静态代理
创始人
2024-05-05 03:47:38
0

文章目录

  • 前言
  • 一、代理模式中的三大角色
  • 二、静态代理引入
    • 1.业务接口
    • 2.目标对象
  • 总结


前言

在Java程序中代理模式的作用:

  • 当一个对象需要收到保护的时候可以考虑使用代理对象去完成某个行为
  • 需要给某个对象的功能进行功能增强的时候,可以考虑找一个代理进行增强
  • A对象无法和B对象直接交互时,也可以使用代理模式来解决

一、代理模式中的三大角色

第一个角色:目标对象(演员)
第二个角色:代理对象(替身演员)
第三个角色:目标对象和代理对象的公共接口(演员和替身演员应该具有相同的行为动作)

使用代理模式的话,对于客户端程序来说,客户端是无法察觉到的,客户端在使用代理对象的时候就像在使用目标对象

在这里插入图片描述

二、静态代理引入

1.业务接口

OrderService

public interface OrderService {void generate();void modify();void detail();
}

2.目标对象

OrderServiceImpl (原业务实现类)

public class OrderServiceImpl implements OrderService{@Overridepublic void generate() {//模拟生成订单的耗时try{Thread.sleep(1234);}catch(Exception e){e.printStackTrace();}System.out.println("订单已生成");}@Overridepublic void modify() {try{Thread.sleep(1234);}catch(Exception e){e.printStackTrace();}System.out.println("订单已修改");}@Overridepublic void detail() {try{Thread.sleep(1234);}catch(Exception e){e.printStackTrace();}System.out.println("查看订单详情");}
}

需求:
项目经理提出一个新的业务需求:需要统计所有业务接口中每一个业务方法的耗时。

解决方案一:硬编码,在每一个业务接口中的每一个业务方法中直接添加统计耗时的程序

缺点一:违背OCP开闭原则
缺点二:代码没有得到复用(相同的代码写了很多遍)

解决方案一修改之后的代码

public class OrderServiceImpl implements OrderService{@Overridepublic void generate() {long begin = System.currentTimeMillis();//模拟生成订单的耗时try{Thread.sleep(1234);}catch(Exception e){e.printStackTrace();}System.out.println("订单已生成");long end = System.currentTimeMillis();System.out.println("耗时"+(end-begin)+"毫秒");}@Overridepublic void modify() {long begin = System.currentTimeMillis();try{Thread.sleep(443);}catch(Exception e){e.printStackTrace();}System.out.println("订单已修改");long end = System.currentTimeMillis();System.out.println("耗时"+(end-begin)+"毫秒");}@Overridepublic void detail() {long begin = System.currentTimeMillis();try{Thread.sleep(546);}catch(Exception e){e.printStackTrace();}System.out.println("查看订单详情");long end = System.currentTimeMillis();System.out.println("耗时"+(end-begin)+"毫秒");}
}

测试程序:

public class Test {public static void main(String[] args) {OrderService orderService = new OrderServiceImpl();orderService.generate();orderService.detail();orderService.modify();}
}

在这里插入图片描述

解决方案二:编写业务类的子类,让子类继承业务类,对每个业务方法进行重写

缺点一:虽然解决了OCP开闭原则,但是这种方式会导致耦合度很高,因为采用了继承关系。继承关系是一种耦合度高的关系,不建议使用
缺点二:代码没有得到复用(相同的代码写了很多遍)

**添加新的子类OrderServiceSub **
之前的业务实现类保持不变

public class OrderServiceSub extends OrderServiceImpl{@Overridepublic void generate() {long begin = System.currentTimeMillis();super.generate();long end = System.currentTimeMillis();System.out.println("耗时"+(end-begin)+"毫秒");}@Overridepublic void modify() {long begin = System.currentTimeMillis();super.modify();long end = System.currentTimeMillis();System.out.println("耗时"+(end-begin)+"毫秒");}@Overridepublic void detail() {long begin = System.currentTimeMillis();super.detail();long end = System.currentTimeMillis();System.out.println("耗时"+(end-begin)+"毫秒");}
}

测试程序:

public class Test {public static void main(String[] args) {OrderService orderService = new OrderServiceSub();orderService.generate();orderService.detail();orderService.modify();}
}

在这里插入图片描述

解决方案三:代理模式

优点一:解决了OCP问题
优点二:采用代理模式的has a,可以降低耦合度
缺点一:如果有一百个业务接口需要写一百个代理类,会造成类爆炸,不好维护,可以使用动态代理来解决这个问题。动态代理还是代理模式,只不过添加了字节码生成技术,可以在内存中为我们动态的生成一个class字节码,这个字节码就是代理类。

代理模式中的代理对象OrderServiceProxy
对于静态代理来说,OrderService就是公共接口,OrderServiceImpl就是目标对象,缺少代理对象。
代理对象和目标对象要有相同的行为,就要实现同一个或同一些接口
客户端在使用代理对象的时候就像在使用目标对象一样
将目标对象作为代理对象的一个属性,这种关系叫做关联关系,比继承关系的耦合度低

    private OrderService target;//这就是目标对象,目标对象一定是实现了OrderService接口

注意:这里要写一个公共接口类型,因为公共接口耦合度低,不能写实现类。通过构造方法赋值

public class OrderServiceProxy implements OrderService{//将目标对象作为代理对象的一个属性,这种关系叫做关联关系,比继承关系的耦合度低private OrderService target;//这就是目标对象,目标对象一定是实现了OrderService接口public OrderServiceProxy(OrderService target) {this.target = target;}@Overridepublic void generate() {long begin = System.currentTimeMillis();//调用目标对象的目标方法target.generate();long end = System.currentTimeMillis();System.out.println("耗时"+(end-begin)+"毫秒");}@Overridepublic void modify() {long begin = System.currentTimeMillis();target.modify();long end = System.currentTimeMillis();System.out.println("耗时"+(end-begin)+"毫秒");}@Overridepublic void detail() {long begin = System.currentTimeMillis();target.detail();long end = System.currentTimeMillis();System.out.println("耗时"+(end-begin)+"毫秒");}
}

测试程序:

public class Test {public static void main(String[] args) {//new OrderServiceImpl()目标对象//new OrderServiceProxy()代理对象OrderService orderService = new OrderServiceProxy(new OrderServiceImpl());//调用代理对象的代理方法orderService.generate();orderService.modify();orderService.detail();}
}

在这里插入图片描述


总结

类和类之间的关系,包括6种关系,其中两个关系是:

  • 泛化关系
  • 关联关系

泛化关系:继承 is a

Cat is a animal
public class Animal(){}
public class Cat extends Animal(){}

关联关系:has a

张三 has a 苹果
public class Person(){
private Apple apple;
}
public class Apple(){}

相比来说:泛化关系的耦合度高于关联关系

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...