代理设计模式,框架AOP思想

文章目录

    • 引言🤪
    • 代理对象(Proxy)
    • 如何开发一个代理对象
    • 开发中的业务层代码冗余问题
    • 开发静态代理类
    • 动态代理

引言🤪

代理 (proxy) ,举个生活中常见的现象,在之前网路还未走进大众的时代里,如果我们想买一些东西,只是直接去店里,现在网络普及了,互联网+shopping,使我们足不出户就可以办很多事,比如网上购物,注意啊,网上购物大多数都是有一个代收点,而不是直接送到你的手上,家里,为什么呢?,因为那样的代价会很大,影响效率,所以出现了代收点,我们再去代收点去拿到网购的货物,完成网购,那么,根据这个现象,如果放在编程中,我们就可以把这个代收点比做成是一个代理对象,在整个购物的过程中起到了一个代收的作用,同时他也介入了购物的一部分,OK

在这里插入图片描述

代理对象(Proxy)

代理:指的是一种设计模式
作用:在整个业务中完成一些 业务之外的附加操作,同时也可以中断整个业务
好处:专注于业务开发,对于一些附加操作,交予代理完成一些繁琐的重复的操作,好耶!

在这里插入图片描述

如何开发一个代理对象

1.代理对象要和原始业务对象有用一个规定,放在面向对象中就是实现同一个接口(interface)
2.代理对象依赖业务对象

开发中的业务层代码冗余问题

ShopService接口

//商品业务的接口
public interface ShopService {
    //添加商品
    void add();
    //下架商品
    void remove();
    //……
}

ShopService接口实现类ShopServiceImpl

public class ShopServiceImpl implements ShopService {
    @Override
    public void add() {
        try {
            System.out.println("开启事务");
            System.out.println("处理添加商品业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void remove() {
        try {
            System.out.println("开启事务");
            System.out.println("处理添下架商品业务逻辑,调用DAO~~~");
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }
}

测试一下

public class ShopTest {
    public static void main(String[] args) {
        ShopServiceImpl shopService = new ShopServiceImpl();
        shopService.add();
        shopService.remove();
    }
}

是没有任何问题的,但是你会发现service控制事务的代码大量冗余,一点也不优雅,在做重复的事情,如果是你,你会怎么优化呢?问题给到你,🤪

开启事务
处理添加商品业务逻辑,调用DAO~~~
提交事务
开启事务
处理添下架商品业务逻辑,调用DAO~~~
提交事务

开发静态代理类

ShopServiceStaticProxy

/*静态代理类和业务类实现同一个接口*/
public class ShopServiceStaticProxy implements ShopService {

    /*静态代理类依赖业务类*/
    private ShopService shopService;

    public void setShopService(ShopService shopService) {
        this.shopService = shopService;
    }

    @Override
    public void add() {
        try {
            System.out.println("开启事务");
            shopService.add();
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }

    @Override
    public void remove() {
        try {
            System.out.println("开启事务");
            shopService.remove();
            System.out.println("提交事务");
        }catch (Exception e){
            System.out.println("回滚事务");
            e.printStackTrace();
        }
    }
}

ShopServiceImpl优化后的专注于业务

public class ShopServiceImpl implements ShopService {
    @Override
    public void add() {
        System.out.println("处理添加商品业务逻辑,调用DAO~~~");
    }

    @Override
    public void remove() {
        System.out.println("处理添下架商品业务逻辑,调用DAO~~~");
    }
}

能否可行,测试,必须行

public class ShopTest {
    public static void main(String[] args) {
        ShopServiceImpl shopService = new ShopServiceImpl();
        ShopServiceStaticProxy shopServiceStaticProxy = new ShopServiceStaticProxy();
        shopServiceStaticProxy.setShopService(shopService);
        shopServiceStaticProxy.add();
        shopServiceStaticProxy.remove();
    }
}
开启事务
处理添加商品业务逻辑,调用DAO~~~
提交事务
开启事务
处理添下架商品业务逻辑,调用DAO~~~
提交事务

perfect,现在看起来优雅很多了

往往在开发我们书写的不仅仅是一个业务层,两个业务层,而我们的业务层会有很多,如果为每一个业务层开发一个静态代理类,不仅没有减轻工作量,甚至让我们的工作量多了一倍不止怎么解决以上这个问题呢?
解决方案:
为业务层在运行过程中动态创建代理类,通过动态代理类去解决我们现有业务层中业务代码冗余的问题

动态代理

有了静态代理的基础之后,来看看更好玩的动态代理,它是spring框架AOP的实现原理,以及很多框架的核心思想及落地实现
GO

通过jdk提供的 Proxy 类,动态为现有的业务生成代理类

参数一:当前线程类加载器 classLoader
参数二:生成代理类的接口类型
参数三:通过代理类对象调用方法时会优先进入参数三中的invoke方Proxy.newProxyInstance(loader, interfaces, h);//返回值就是动态代理对象

AOP的原理就是对动态代理的封装

还有 MyBatis 框架中的 getMapper(xxx.class),就是使用了动态代理对象

public class TestDynamicProxy {
    public static void main(String[] args) {
        //参数1: classLoader 类加载器
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        //参数2: Class[] 动态代理对象的接口类型的数组
        Class[] classes = {ShopService.class};
        //参数3: InvocationHandler接口类型 invoke 方法 写附加操作

        ShopService userServiceDyProxy = (ShopService) Proxy.newProxyInstance(classLoader, classes, new InvocationHandler() {
            @Override
            //通过动态代理对象调用自己里面代理方法时会优先指定InvocationHandler类中invoke
            // invoke方法参数
            //1. 当前创建好的代理对象
            //2. 当前代理对象执行的方法对象
            //3. 当前代理对象执行方法的参数
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("当前执行的方法:" + method.getName());
                try {
                    System.out.println("开启事务");
                    //调用目标类中的业务方法
                    Object invoke = method.invoke(new ShopServiceImpl(), args);
                    System.out.println("提交事务");
                    return invoke;
                }catch (Exception e){
                    System.out.println("回滚事务");
                    e.printStackTrace();
                }
                return null;
            }
        });
        System.out.println(userServiceDyProxy.getClass());
        userServiceDyProxy.remove();
        userServiceDyProxy.add();
    }
}
class com.sun.proxy.$Proxy0
当前执行的方法:remove
开启事务
处理添下架商品业务逻辑,调用DAO~~~
提交事务
当前执行的方法:add
开启事务
处理添加商品业务逻辑,调用DAO~~~
提交事务

完美完成,Perfect realization,尽管动态代理的代码很难理解,但是这是必经之路,加油,战胜它,奥里给,这就是全部内容了,拜拜了 🚀

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java——构造器(构造方法)和 this

一、什么是构造器 构造器(Constructor)是Java类的一种特殊方法,用于初始化对象的状态。构造器在创建对象时被调用,可以对对象的成员变量进行初始化。 我之前的文章《Java——类和对象-CSDN博客》中也提到了构造器。 二、构造器…

pc repair

pc repair 修理电脑,换配件

【猫狗分类】Pytorch VGG16 实现猫狗分类1-数据清洗+制作标签文件

Pytorch 猫狗分类 用Pytorch框架,实现分类问题,好像是学习了一些基础知识后的一个小项目阶段,通过这个分类问题,可以知道整个pytorch的工作流程是什么,会了一个分类,那就可以解决其他的分类问题&#xff0…

马斯克在2024年特斯拉股东大会上的年度发言

马斯克表示,“如果市盈率是20或25倍,那就意味着,光是Optimus就能带来20万亿美元的市值。而自动驾驶汽车的市值可能在5到10万亿美元之间。因此,特斯拉的市值达到当今市值最高公司的10倍,是可以想象的,也是有…

一个在C#中集成Python的例子

一个在C#中集成Python的例子。在C#中可以执行Python脚本,在Python中也可以调用C#宿主中的功能(clr.AddReference(Business))。 文件说明 Debug为执行目录 Mgr.exe为执行文件 Py\init.py为python初始化脚本 Py\Lib.zip为python需要的模块&…

大数据实训项目(小麦种子)-02、实训项目整体功能介绍与演示

文章目录 前言界面及功能描述实现功能描述技术选型界面展示首页界面功能1:HDFS,选择文件上传文件详细步骤 功能2:MapReduce预处理数据功能3:Hbase存储小麦种子数据并查询前10条记录功能4:Hive分析原始csv文件数据并ech…

【GO-OpenCV】go-cv快速配置

最近对golang实现目标检测心血来潮,尝试在没有sudo权限的平台配置go-cv,有所发现,索性多个平台都做尝试 安装Go语言(Golang) 通过包管理器安装(适用于Debian/Ubuntu)(有点慢) 更新包列表: sud…

简单的基于小波变换的图像压缩(Python)

2023 沃尔夫数学奖得主,给了杜克大学的Ingrid Daubechies(多贝西)教授 以色列沃尔夫基金会理事会成员 Michael Lin 教授在周二宣布: “Ingrid Daubechies is awarded the Wolf Prize for her work in the creation and development of wavel…

搭建k8s集群报错unknown command “\u00a0“ for “kubeadm init“

搭建k8s报错unknown command “\u00a0” for “kubeadm init” 网上搜了一下,是因为复制过来的命令前面包含了空格,将复制的命令放到idea可以清楚看到几个命令前面有空格,删除掉就好了,记录一下

设计模式-享元模式Flyweight(结构型)

享元模式(Flyweight) 享元模式是一种结构型模式,它主要用于减少创建对象的数量,减少内存占用。通过重用现有对象的方式,如果未找到匹配对象则新建对象。线程池、数据库连接池、常量池等池化的思想就是享元模式的一种应用。 图解 角色 享元工…

【团队成长】2024-24周周报-第一次组会人员分工48期推文预告

大家好!我们是IndustryOR 团队,致力于分享业界落地的算法技术。欢迎关注微信公众号/知乎/CSDN【运筹匠心】 。 记录人:张哲铭,算法专家,某互联网大厂 【团队成长/个人成长】系列的推文会以 【工作周报】 的方式记录Ind…

【机器学习】人工智能与气候变化:利用深度学习与机器学习算法预测和缓解环境影响

📝个人主页:哈__ 期待您的关注 目录 🔥引言 1.1 背景介绍 1.2 人工智能与机器学习的崛起 1.3 本文内容概述 🔨气候变化的挑战 2.1 现今气候变化带来的影响和挑战 2.2 引发关注的气候变化趋势和数据 🤖人工智能…

使用SpringBoot对接Kafka

Kafka是什么,以及如何使用SpringBoot对接Kafka 一、Kafka与流处理 我们先来看看比较正式的介绍:Kafka是一种流处理平台,由LinkedIn公司创建,现在是Apache下的开源项目。Kafka通过发布/订阅机制实现消息的异步传输和处理。它具有高…

VMware Workstation安装及使用详细教程

如何安装VMware Workstation的详细教程 一、准备工作 1. 下载VMware Workstation: 访问VMware官方网站,找到VMware Workstation的下载页面。根据您的操作系统(Windows或macOS)选择相应的版本进行下载。确保您的计算机满足VMwar…

牛客小白月赛96 解题报告 | 珂学家

前言 题解 A. 最少胜利题数 签到 n1 len(set(input())) n2 len(set(input()))if n1 < n2:n1, n2 n2, n1print (-1 if n1 6 else n1 - n2 1)B. 最少操作次数 思路: 分类讨论 只有-1,0,1,2这四种结果 特判 01, 10 n int(input()) s input()# 枚举 from collectio…

vue之一键部署的shell脚本和它的点.bat文件、海螺AI、ChatGPT

MENU 前言vite.config.ts的配置deploy文件夹的其他内容remote.shpwd.txtdeploy.bat 前言 1、在src同级新建deploy.bat文件&#xff1b; 2、在src同级新建deploy文件夹&#xff0c;文件夹中新建pwd.txt和remote.sh文件&#xff1b; 3、配置好后&#xff0c;直接双击deploy.bat文…

Java_FileIO流

存储数据的方案 有些数据想长久保存起来&#xff0c;咋整&#xff1f; 文件时非常重要的存储方式&#xff0c;在计算机硬盘中。 即便断电&#xff0c;或者程序终止了&#xff0c;存储在硬盘文件中的数据也不会丢失。 File File 是Java.io.包下的类&#xff0c;File类对象&…

C++ string字符串的使用和简单模拟实现

目录 前言 1. string简介 2. string的使用和简单模拟实现 2.1 string类的定义 2.2 string(),~string()和c_str() 2.2 size&#xff0c;重载符号[ ]&#xff0c;begin和end函数 2.3 push_back&#xff0c;reserve&#xff0c;append&#xff0c;运算符重载 2.4 insert和…

DDPM公式推导(三)

2 Background 扩散模型【53】是一种以 p θ ( x 0 ) : ∫ p θ ( x 0 : T ) d x 1 : T p_\theta\left(\mathbf{x}_0\right):\int p_\theta\left(\mathbf{x}_{0: T}\right) d \mathbf{x}_{1: T} pθ​(x0​):∫pθ​(x0:T​)dx1:T​ 形式的潜在变量模型&#xff0c;其中 x 1…

机器真的能思考、学习和智能地行动吗?

In this post, were going to define what machine learning is and how computers think and learn. Were also going to look at some history relevant to the development of the intelligent machine. 在这篇文章中&#xff0c;我们将定义机器学习是什么&#xff0c;以及…