代理模式-P19

news2024/11/26 14:41:02

静态代理:

创建项目:

Rent

package com.Li.demo01;

//租房
public interface Rent {
    public void rent();
}

 Proxy:

package com.Li.demo01;
//中介(负责找房东)
public class Proxy implements Rent{
    //
    private Host host;

    public Proxy() {
    }

    public Proxy(Host host) {
        this.host = host;
    }

    @Override
    public void rent() {
        host.rent();
    }
}

Host:

package com.Li.demo01;

//房东
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东要出租房子!");
    }
}

Client:

package com.Li.demo01;

public class Client {
    public static void main(String[] args) {
        Host host = new Host();
        //代理
        Proxy proxy = new Proxy(host);
        proxy.rent();
    }
}
由于中介也需要房东,所以需要在此之前new一个房东。

你可能认为有没有效果都一样,但是在这个过程中,中介可以有自己的属性和方法。增加自己想要的内容。

修改之后

Proxy:(增加了自己的特有方法)

package com.Li.demo01;
//中介(负责找房东)
public class Proxy implements Rent{
    //
    private Host host;

    public Proxy() {
    }

    public Proxy(Host host) {
        this.host = host;
    }

    @Override
    public void rent() {
        seeHouse();
        host.rent();
        hetong();
        fare();
    }

    //看房
    public void seeHouse(){
        System.out.println("中介带你看房");
    }

    //签合同
    public void hetong(){
        System.out.println("签租赁合同");
    }

    //收费
    public void fare(){
        System.out.println("收中介费");
    }

}

此时就已经经过了中介之手,租到房了。

 


拓展:

新建demo02

UserService:

package com.Li.demo02;

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void query();
}

UserServiceImpl:

package com.Li.demo02;

public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("增加了一个用户");
    }

    @Override
    public void delete() {
        System.out.println("删除了一个用户");
    }

    @Override
    public void update() {
        System.out.println("修改了一个用户");
    }

    @Override
    public void query() {
        System.out.println("查询了一个用户");
    }
}

UserServiceProxy:(代理类)(重点!)========相当于复制了一份原本的内容,这样操作出错的时候也不会影响原本内容。

package com.Li.demo02;

public class UserServiceProxy implements UserService{

    //相当于在Proxy里面调取了UserServiceImpl
    private UserServiceImpl userService;

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }

    @Override
    public void add() {
        log("add");
        userService.add();
    }

    @Override
    public void delete() {
        log("delete");
        userService.delete();
    }

    @Override
    public void update() {
        log("update");
        userService.update();
    }

    @Override
    public void query() {
        log("query");
        userService.query();
    }

    //日志方法
    public void log(String msg){
        System.out.println("[debug] 使用了"+msg+"方法");
    }
}

Client:(测试)

package com.Li.demo02;

public class Client {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();

        UserServiceProxy proxy = new UserServiceProxy();
        proxy.setUserService(userService);//中介(proxy)代理userService

        proxy.add();
    }
}

测试结果:

AOP就是横切进去,用来完善之前的业务。

 


动态代理:

· 动态代理和静态代理角色一样
· 动态代理的代理类是动态生成的,不是我们直接写好的!
· 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
        ·基于接口 — JDK动态代理【我们在这里使用】
        ·基于类:cglib
        ·java字节码实现:javassist
需要了解两个类:Proxy:代理;InvocationHandler:调用处理程序。

Rent(接口)

package com.Li.demo03;

//租房
public interface Rent {
    public void rent();
}
Host
package com.Li.demo03;

//房东
public class Host implements Rent {
    @Override
    public void rent() {
        System.out.println("房东要出租房子!");
    }
}

ProxyInvocationHandler(核心)(就相当于中介)

package com.Li.demo03;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//等会我们会用这个类,自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {

    //被代理的接口
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }


    //生成得到代理类
    //(返回三个参数:用哪个类加载器去加载代理对象(中介),被代理的对象(房东),谁来进行这种new操作(运用invoke来操作)生成中介(也就是谁来生成中介))
    //通过本程序的类加载器,来加载需要被代理的角色,生成代理类(三个参数的解释)
    //一般只需要修改中间的参数就可以了
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
    }

    //处理代理实例,并返回结果(真正的中介,上面的中介相当于是复制之前的内容,这个相当于可以在复制内容上面修改)
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        seeHouse();
        //动态代理的本质,就是使用反射机制实现!
        Object invoke = method.invoke(rent, args);
        fare();

        return invoke;
    }


    public void seeHouse(){
        System.out.println("中介看房子");
    }

    public void fare(){
        System.out.println("收中介费");
    }







}

Client:(测试)

package com.Li.demo03;

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();

    }
}

 

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

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

相关文章

Redis安装及使用(WindowsLinux)

Windows 1.下载 下载地址:Releases tporadowski/redis GitHub。 目前最新5.0.14 2.解压 3.先后打开redis-server.exe和redis-cli.exe两个文件(一定要按顺序) 4.使用 正常使用在redis-cli.exe里面输入各种命令(使用期间redis…

7、系统管理

文章目录7、系统管理7.1 Linux 中的进程和服务7.2 service 服务管理(CentOS 6 版本-了解)7.2.1 基本语法7.2.2 经验技巧7.2.3 案例实操(1)查看网络服务的状态(2)停止网络服务(3)启动…

基于JAVA的个人博客论坛系统的设计与实现参考【数据库设计、源码、开题报告】

在学校开发搭建一个什么项目最有成就感,那肯定就是搭建「个人博客」呀,然后把自己平时的学习笔记写到博客里,这时你的笔记就是**云笔记**,就再也不会出现因为本地文件丢失而感到痛心的事情。 而且,还可以把你的个人博客…

艾美捷小鼠肿瘤坏死因子α-ELISpot试剂盒使用说明

肿瘤坏死因子-α 肿瘤坏死因子-α(TNF-α,也称为TNF-α、TNF-a、TNF-a和肿瘤坏死因子α)由许多不同的细胞类型产生,例如单核细胞、巨噬细胞、T细胞和B细胞。TNF-α的许多作用包括保护细菌感染、细胞生长调节、免疫系统调节和感染…

Kotlin 使用vararg可变参数

文章目录背景Kotlin中使用可变参数对Kotlin可变参数反编译资料背景 一般在项目开发中,我们经常会在关键节点上埋点,而且埋点中会增加一些额外参数,这些参数通常是成对出现且参数个数是不固定的。如下: //定义事件EVENT_ID const…

云原生|kubernetes |使用Prometheus监控k8s cAdvisor篇(一)(centos)

前言: 为了能够提前发现kubernetes集群的问题以及方便快捷的查询容器的各类参数,比如,某个pod的内存使用异常高企 等等这样的异常状态(虽然kubernetes有自动重启或者驱逐等等保护措施,但万一没有配置或者失效了呢)&am…

PAM exec模块监控服务器ECS登录用户及IP,触发登录后,发送至钉钉

PAM 模块pam_exec ,用于运行外部命令 PAM 项作为环境变量导出:* PAM_RHOST , PAM_RUSER , PAM_SERVICE , PAM_TTY , PAM_USER 和 PAM_TYPE *,其中包含以下模块类型之一:account&…

【深度学习】实验5布置:滴滴出行-交通场景目标检测

DL_class 学堂在线《深度学习》实验课代码报告(其中实验1和实验6有配套PPT),授课老师为胡晓林老师。课程链接:https://www.xuetangx.com/training/DP080910033751/619488?channeli.area.manual_search。 持续更新中。 所有代码…

电脑c盘分区太小如何可以扩大,电脑c盘不够用了,如何给电脑分区

C盘是很重要的系统盘,会影响到整个系统的正常化运行。如果电脑c盘分区太小如何可以扩大? 一、清理C盘的垃圾文件 C盘分区不足的原因之一就是因为C盘的垃圾文件没有及时清理,导致垃圾文件越来越多,电脑越来越卡,所以&a…

2022最新软件测试面试八股文,全网最全最新,堪称地表最强

前言 2022秋招已经结束,在应聘过程中相信很多同学都感受到了目前测试就业越来越严峻,内卷也成了测试领域的代名词了。的一个HR朋友告诉我,由于门槛较低,现在普通测试岗(偏功能)的投递比已经将近100&#x…

如何让皮卡丘在网页上跑起来

说在前面 🎈相信很多80、90后的朋友,对QQ宠物印象非常深刻,每次开机宠物就会自动跑出来。曾经很多人想饿死他,但失败了;也有很多人一上线就退出,但就是不愿因取消“开机自动开启”的勾选。2018年09月15日&a…

Adobe Audition CS6 下载与安装教程

文章目录Adobe Audition CS6 简介(一)Adobe Audition cs6软件功能(二)Adobe Audition cs6软件特色(三)Adobe Audition cs6新增功能一,Adobe Audition CS6 下载二,Adobe Audition CS6…

ReactHook技巧

ReactHook技巧 文章目录ReactHook技巧一 概念二 useState三 useEffect3.1 无需清除副作用(**Effect**)3.2 需要清除副作用(**Effect**)3.3 控制(**Effect**)调用次数一 概念 1.什么是hook? 2.为什么要用hook? -: 为函数组件提供状态管理能力, 扩展 -: 在Function组件中勾入…

常用的国际物流运输方式有哪些

目前我国从事跨境电商行业的人才众多,不仅促进了我国外贸业务的活力,也促进了国际物流业的发展。国际货贸运输涉及陆运物流、海运物流、空运物流、管道物流、多式联运物流、邮运物流等多种运输方式。一、陆运物流 陆运物流含公路和铁路联运物流&#xff…

C语言百日刷题第十天

前言 今天是刷题第10天,放弃不难,但坚持一定很酷~ 快来跟我一起刷题吧。 C语言百日刷题第十天前言81.连接两个字符串82.输入一行字符,分别统计其中英文字母、空格、数字和其他字符的个数。83.写一个排序函数实现数组从小到大的排序84.字母的大…

SPARKSQL3.0-DataFrameAPI与spark.sql()区别源码分析

一、前言: 阅读本节需要先掌握spark-sql内部执行的基本知识: SessionState Unresolved阶段 Analyzer阶段中queryExecution的介绍 二、区别 spark.sql的执行顺序为: sql字符串 -> antlr4解析成AST语法树 -> unreolved解析成logicalPlan ->…

云计算正当时!将你的Java项目容器化

将您的 Java 应用程序 Docker 化 长按关注《Java学研大本营》,加入读者群,分享更多精彩 扫码关注《Java学研大本营》,加入读者群,分享更多精彩 随着每个人都转向 Kubernetes,知道如何对应用程序进行 Dockerize 是件好…

IPv6转换难点分析之一:国家监测指标-中科三方

从IPv4过渡到IPv6就像是“打破一个旧世界,创建一个新世界”,注定要经历一个长期的过程,但终究会实现。 一、IPv6过渡转换的障碍 目前互联网上还是以IPv4设备为主,不可能迅速过渡到IPv6,这主要受制于以下几个方面: &…

Nat. Mach. Intell2021 | MolCLR+:基于GNN的分子表征对比学习

原文标题:Molecular Contrastive Learning of Representations via Graph Neural Networks 代码:https://github.com/yuyangw/MolCLR 一、问题提出 首先,分子信息难以完全表示。例如,基于字符串的表示,如SMILES和SE…

未来展望:Starday供应链火力全开,为跨境电商再添动力!

2022年末将至,回顾这“命途多舛”的一年,也是令人非常唏嘘。近日,联合国发布《2022年年中世界经济形势与展望》报告,该报告指出正处于疫情恢复期的全球经济可能又到了一场新危机的边缘。据相关统计显示,2022年相比于20…