spring之静态代理

news2024/11/17 9:38:57

文章目录

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


前言

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

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

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

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

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

在这里插入图片描述

二、静态代理引入

1.业务接口

OrderService

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

2.目标对象

OrderServiceImpl (原业务实现类)

public class OrderServiceImpl implements OrderService{
    @Override
    public void generate() {
        //模拟生成订单的耗时
        try{
            Thread.sleep(1234);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("订单已生成");
    }

    @Override
    public void modify() {
        try{
            Thread.sleep(1234);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("订单已修改");
    }

    @Override
    public void detail() {
        try{
            Thread.sleep(1234);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("查看订单详情");
    }
}

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

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

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

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

public class OrderServiceImpl implements OrderService{
    @Override
    public 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)+"毫秒");
    }

    @Override
    public 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)+"毫秒");
    }

    @Override
    public 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{
    @Override
    public void generate() {
        long begin = System.currentTimeMillis();
        super.generate();
        long end = System.currentTimeMillis();
        System.out.println("耗时"+(end-begin)+"毫秒");
    }

    @Override
    public void modify() {
        long begin = System.currentTimeMillis();
        super.modify();
        long end = System.currentTimeMillis();
        System.out.println("耗时"+(end-begin)+"毫秒");
    }

    @Override
    public 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;
    }

    @Override
    public void generate() {
        long begin = System.currentTimeMillis();
        //调用目标对象的目标方法
        target.generate();
        long end = System.currentTimeMillis();
        System.out.println("耗时"+(end-begin)+"毫秒");
    }

    @Override
    public void modify() {
        long begin = System.currentTimeMillis();
        target.modify();
        long end = System.currentTimeMillis();
        System.out.println("耗时"+(end-begin)+"毫秒");
    }

    @Override
    public 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(){}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136464.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java内存模型(JMM)详解!

文章目录什么是JMM?现代计算机内存模型缓存一致性JMM内存模型与计算机内存模型的关系线程间通信JMM三大问题原子性可见性有序性什么是JMM? JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。 JMM可以理解为是一个规范,一个抽象概念,并不真实…

Java 单元测试

目录 一、Junit 1.1、单元测试初始化与清理资源 1.2、捕获异常 1.3、条件测试 1.4、标记失效测试方法 1.5、参数化测试 单元测试:是对最小功能单元编写的测试代码。 示例,当开发好一个 Java 阶乘的方法。 n! 1 x 2 x 3 x ..…

CRM软件哪个好?该如何选择?

CRM软件哪个好?该如何选择? CRM是集营销、销售、服务为一体的围绕客户全生命周期管理的系统,在各行各业的数字化转型大潮中,作为以消费者、终端用户、客户为主导的企业经营管理核心系统,CRM选型的难度和复杂度也在不断…

关于ETL的两种架构(ETL架构和ELT架构)

ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程。ETL一词较常用在数据仓库,但其对象…

Java的JVM垃圾回收机制GC概述

JVM——GC机制1、什么是GC?2、GC算法的总体概述3、JVM所处的位置4、JVM整体结构5、JVM架构模型6、Java垃圾回收机制优缺点7、GC主要关注的区域垃圾回收算法:标记阶段,引用计数循环引用标记阶段:可达性分析算法GC root可以是哪些&a…

JavaScript代码题--以及一些奇奇怪怪的发现

解析 let a{b:10,c:{d:[11,12],e:13}},实现 10111213 效果 解 const a{b:10,c:{d:[11,12],e:13}}function sum(obj) {let total 0;const value Object.values(obj)value.forEach(item>{total typeof item number ? item : sum(item)})return total }const …

Java家教系统家教网站家教兼职系统

简介: 用户可以注册成为学员也可以是教员。教员发布家教信息,学员根据自己的要求查找符合自己的教员。学员预约教员的某一天去家教,教员可以在个人中心里查看,是否接受该预约。在教员接受或拒绝之前,学员随时可以取消…

数据库,计算机网络、操作系统刷题笔记23

数据库,计算机网络、操作系统刷题笔记23 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,oracle…

基于 Vue 制作一个猜拳小游戏

目录前言:项目效果展示:对应素材:代码实现思路:实现代码:总结:前言: 在工作学习之余玩一会游戏既能带来快乐,还能缓解生活压力,跟随此文一起制作一个小游戏吧。 描述&…

【2042. 检查句子中的数字是否递增】

来源:力扣(LeetCode) 描述: 句子是由若干 token 组成的一个列表,token 间用 单个 空格分隔,句子没有前导或尾随空格。每个 token 要么是一个由数字 0-9 组成的不含前导零的 正整数 ,要么是一个…

ORA-00600 kcratr_nab_less_than_odr 问题处理

问题:ORA-00600: 内部错误代码, 参数: [kcratr_nab_less_than_odr], [1], [196495], [39399], [39460], [], [], [], [], [], [], []导致原因:可能是由于服务器宕机,控制文件的缺失,或者在线日志文件在实例恢复时不完整1、数据库未…

5G边缘计算网关助力5G工业物联网智能化建设

5G边缘计算,凭借高带宽、高可靠、低时延、移动性等特性,推动工业生产物联网发展趋势,实现工业更快、更精准通信及数据共享。边缘计算网关下5G工业物联网远程感知生产一线,工控数字化、自动化、智能化,降低人物力资源成…

LeetCode 2042. 检查句子中的数字是否递增

【LetMeFly】2042.检查句子中的数字是否递增 力扣题目链接:https://leetcode.cn/problems/check-if-numbers-are-ascending-in-a-sentence/ 句子是由若干 token 组成的一个列表,token 间用 单个 空格分隔,句子没有前导或尾随空格。每个 tok…

【计算机体系结构】指令集并行(ILP)动态调度算法:Tomasulo实现代码(Tomasulo Algorithm Implementation)

Tomasulo Algorithm Implementation (本文章仅提供算法实现过程,具体算法思想请查阅教科书) 如果觉得这篇文章有用,请记得点个赞并收藏哦! 1.Introduction Tomasulo算法用于指令的动态调度,允许乱序执行…

C C++内存对齐以及特殊类的大小

目录C语言内存对齐现象内存对齐规则为什么存在内存对齐如果struct or class中存在成员函数时的大小空类大小为1Cclass存在虚函数时的大小C语言 内存对齐现象 C语言中结构体的大小往往不是结构体中各种数据类型的加和,因为存在内存对齐; struct S {double d;//8字…

Linux常用系统日志

文章目录一 常用系统日志二 系统日志优先级三 其他日志文件一 常用系统日志 日志文件用途/var/log/messages记录大多数系统日志信息,包括启动、IO错误、网络和程序等问题/var/log/secure记录安全和身份验证等相关消息和错误/var/logrsyslog将所有日志文件写入到该目…

Nacos 漏洞利用

Nacos 漏洞利用 1.漏洞描述: Alibaba Nacos是阿里巴巴推出来的一个新开源项目,是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。致力于帮助发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,可以快速实现动态…

ASP.NET企业智能办公OA系统源码带文档【源码免费分享】

ASP.NET企业智能办公OA系统源码带文档 需要源码学习可私信我获取! 本系统特色功能: 1:自定义工作流程,系统所有参数可自定义配置,支持多分公司、多部门架构 2:采用三层结构设计软件,系统扩容性…

vivo 实时计算平台建设实践

作者:vivo 互联网实时计算团队- Chen Tao 本文根据“2022 vivo开发者大会"现场演讲内容整理而成。 vivo 实时计算平台是 vivo 实时团队基于 Apache Flink 计算引擎自研的覆盖实时流数据接入、开发、部署、运维和运营全流程的一站式数据建设与治理平台。 一、v…

【云边有个小卖部】阅读笔记

童年就像童话,这是他们在童话里第一次相遇。 那么热的夏天,少年的后背被女孩的悲伤烫出一个洞,一直贯穿到心脏。 刘十三被欺负得最惨,却想保护凶巴巴的程霜。 每当她笑的时候,就让他想起夏天灌木丛里的萤火虫&#xff…