JDK 动态代理(Spring AOP 的原理)(面试重点)

news2024/11/26 20:31:59

代理模式

        也叫委托模式.定义:为其他对象提供⼀种代理以控制对这个对象的访问.它的作⽤就是通过提供⼀个代理类,让我们 在调⽤⽬标⽅法的时候,不再是直接对⽬标⽅法进⾏调⽤,⽽是通过代理类间接调⽤,在某些情况下,⼀个对象不适合或者不能直接引⽤另⼀个对象,⽽代理对象可以在客⼾端和⽬标对象之间起到中介的作⽤.

        使⽤代理前:

使⽤代理后:

        由于静态代理基本不用,所以直接介绍动态代理

        其中静态代理表示在创建代理对象时就已经知道了目标对象是谁,以及要代理执行的操作是什么

        而动态代理就表示在程序运行时根据需要代理的内容来动态的创建代理对象

JDK 动态代理类实现步骤 

        1. 定义⼀个接口(目标对象要进行的操作)及其实现类(目标对象)(静态代理中的 HouseSubject 和 Landlord )

        2. 实现 InvocationHandler 接口并重写 invoke ⽅法,在 invoke ⽅法中我们会调⽤⽬标⽅法(被代理类的⽅法)并⾃定义⼀些处理逻辑(定义代理对象的逻辑)

        3. 通过 Proxy.newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h) ⽅法创建代理对象

1.首先定义接口 HouseSubject 声明 目标对象需要被代理的操作

//声明房东(目标对象)要执行的相关操作
public interface HouseSubject {
    void rentHouse();   //出租房子
    void saleHouse();   //卖房子
}

2.定义 Landlord 类(目标类)实现  HouseSubject 接口

//房东(目标对象)
public class Landlord implements HouseSubject{
    @Override
    public void rentHouse() {
        System.out.println("房东出租房子");
    }

    @Override
    public void saleHouse() {
        System.out.println("房东卖房子");
    }
}

3.定义 DynamicProxy 类(声明了动态代理的逻辑)实现 InvocationHandler 接口并重写 invoke ⽅法

// JDK 动态代理(通过 JDK 提供的 api 实现动态代理)
public class DynamicProxy implements InvocationHandler {
    private Object target;  //目标对象

    public DynamicProxy(Object target){
        this.target=target;
    }

    //重写 InvocationHandler 接口中的 invoke 方法,执行目标对象需要被代理的方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("中介接手,开始代理");
        //执行目标对象中的方法 target 是目标对象,第二个参数固定传入 args
        Object result=method.invoke(target,args);
        System.out.println("中介离手,结束代理");
        return result;
    }
}

4.定义 DynamicMain 类来创建代理对象并使用

//创建代理对象并使用
public class DynamicMain {
    public static void main(String[] args) {
        //实例化实现了 HouseSubject 接口的对象
        //因为 JDK 动态代理只能代理实现了接⼝的⼀些类
        HouseSubject target=new Landlord();

        //创建代理对象
        HouseSubject proxy=(HouseSubject) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                new Class[]{HouseSubject.class},
                new DynamicProxy(target)
        );

        proxy.rentHouse();
        proxy.saleHouse();
    }
}

        其中创建代理对象用到了 JDK 内置的 Proxy 类调用静态方法 newProxyInstance()创建代理对象

        代理对象的类型是接口  HouseSubject ,直接调用其中的方法,代理对象就能代理目标对象执行相应的操作

        Proxy 类的 newProxyInstance() 方法介绍

public static Object newProxyInstance(
    ClassLoader loader,
    Class<?>[] interfaces,
    InvocationHandler h) throws IllegalArgumentException{
 //...代码省略  
}

        其中 loader :类加载器,⽤于加载代理对象(目标对象的类加载器,注意创建目标对象时要用接口 HouseSubject 引用

                interfaces:被代理类实现的⼀些接⼝(目标类实现的接口)(这个参数的定义,也决定了JDK动态代理只能代理实现了接⼝的 ⼀些类)

                h:实现了 InvocationHandler 接⼝的对象(声明了动态代理逻辑的对象 -> DynamicProxy 的对象)

                

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

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

相关文章

Stream toList不能滥用以及与collect(Collectors.toList())的区别

Stream toList()返回的是只读List原则上不可修改&#xff0c;collect(Collectors.toList())默认返回的是ArrayList,可以增删改查 1. 背景 在公司看到开发环境突然发现了UnsupportedOperationException 报错&#xff0c;想到了不是自己throw的应该就是操作collection不当。 发…

Jetbrains Writerside 使用教程

系列文章目录 前言 一、入门 Writerside 是基于 IntelliJ 平台的 JetBrains 集成开发环境。使用它可以编写、构建、测试和发布技术文档。 如果你想将 Writerside 作为另一个 JetBrains IDE 的插件&#xff0c;请参阅 Writerside 作为插件。 1.1 安装 Writerside&#xfeff;…

vue路由-全局前置守卫

1. 介绍 详见&#xff1a;全局前置守卫网址 使用场景&#xff1a; 对于支付页&#xff0c;订单页等&#xff0c;必须是登录的用户才能访问的&#xff0c;游客不能进入该页面&#xff0c;需要做拦截处理&#xff0c;跳转到登录页面 全局前置守卫的原理&#xff1a; 全局前置…

QT+opencv源码编译

时间记录&#xff1a;2024/1/20 一、版本介绍 QT5.12.7cmake3.22.0opencv4.5.4 二、编译步骤 &#xff08;1&#xff09;下载opencv源码&#xff0c;然后安装&#xff0c;opencv的安装即对源码的解压过程&#xff0c;解压后的文件目录如下 &#xff08;2&#xff09;openc…

stm32 FOC 电机介绍

今年开始学习foc控制无刷电机&#xff0c;这几天把所学整理一下&#xff0c;记录一下知识内容。 前言: 为什么要学习FOC? 1.电机控制是自动化控制领域重要一环。 2.目前直流无刷电机应用越来越广泛&#xff0c;如无人机、机械臂、云台、仿生机器人等等。 需要什么基础&…

最长公共前缀(Leetcode14)

例题&#xff1a; 分析&#xff1a; 我们可以先定义两个变量 i &#xff0c; j&#xff0c; j表示数组中的每一个字符串&#xff0c; i 表示每个字符串中的第几个字符。一列一列地进行比较&#xff0c;先比较第一列的字符&#xff0c;若都相同&#xff0c;则 i &#xff0c;继…

字节跳动 ByteHouse 云原生之路 – 计算存储分离与性能优化

01 起源 ByteHouse 的故事从字节跳动对于先进数据处理和分析的需求开始&#xff0c;这一需求随着公司业务规模的迅速扩张而日益增长&#xff0c;起源是对开源数据库管理系统 ClickHouse 的改造和增强。面对数据处理的高延迟、大规模数据操作的复杂性以及数据存储和处理成本的上…

记录一次QT乱码问题

问题描述 在敲陆文周的书《QT5开发及实例》的示例代码时&#xff0c;出现乱码&#xff0c;如下图所示 具体代码如下 Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);ui->treeWidget->clear();int groupSize 2;int ite…

Unity SnapScrollRect 滚动 匹配 列表 整页

展示效果 原理: 当停止滑动时 判断Contet的horizontalNormalizedPosition 与子Item的缓存值 相减,并得到最小值&#xff0c;然后将Content horizontalNormalizedPosition滚动过去 使用方式&#xff1a; 直接将脚本挂到ScrollRect上 注意&#xff1a;在创建Content子物体时…

蓝桥杯练习题(十二)

&#x1f4d1;前言 本文主要是【算法】——蓝桥杯练习题&#xff08;十二&#xff09;的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他…

list下

文章目录 注意&#xff1a;const迭代器怎么写&#xff1f;运用场合&#xff1f; inserterase析构函数赋值和拷贝构造区别&#xff1f;拷贝构造不能写那个swap,为什么&#xff1f;拷贝构造代码 面试问题什么是迭代器失效&#xff1f;vector、list的区别&#xff1f; 完整代码 注…

微信公众号服务器配置启用, Java示例

微信公众号接入指南文档https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html 在微信公众号的服务器配置中&#xff0c;首先需要编写Java代码来处理微信服务器的验证请求。以下是Java示例代码&#xff0c;然后我将为你提供启用服务器配置…

centos7安装Redis7.2.4

文章目录 下载Redis解压Redis安装gcc依赖&#xff08;Redis是C语言编写的&#xff0c;编译需要&#xff09;编译安装src目录下二进制文件安装到/usr/local/bin修改redis.conf文件启动redis服务外部连接测试 参考&#xff1a; 在centos中安装redis-5.0.7 Memory overcommit must…

记录一下uniapp 集成腾讯im特别卡(未解决)

uniapp的项目运行在微信小程序 , 安卓 , ios手机三端 , 之前这个项目集成过im,不过版本太老了,0.x的版本, 现在需要添加客服功能,所以就升级了 由于是二开 , 也为了方便 , 沿用之前的webview嵌套腾讯IM的方案 , 选用uniapp集成ui ,升级之后所有安卓用户反馈点击进去特别卡,几…

华为FusionStorage Block、OceanStor 100D、OceanStor pacific的区别

华为FusionStorage Block、OceanStor 100D、OceanStor pacific的区别&#xff1f; 华为块存储到底是叫什么呢&#xff1f; 有接触过华为块存储产品的小伙伴肯定都有疑惑&#xff0c;在FusionStorage 、FusionStorage Block、OceanStor 100D、OceanStor pacific等等的名词中&a…

基于SpringBoot Vue高校失物招领系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

自然语言推断:注意力之注意(Attending)

注意&#xff08;Attending&#xff09; 第一步是将一个文本序列中的词元与另一个序列中的每个词元对齐。假设前提是“我确实需要睡眠”&#xff0c;假设是“我累了”。由于语义上的相似性&#xff0c;我们不妨将假设中的“我”与前提中的“我”对齐&#xff0c;将假设中的“累…

【复现】Apache Solr信息泄漏漏洞_24

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 Apache Solr是一个独立的企业级搜索应用服务器&#xff0c;它对外提供类似于Web-service的API接口。用户可以通过http请求&#x…

《Python数据分析技术栈》第03章 03 可视化各级数据(Visualizing various levels of data)

03 可视化各级数据&#xff08;Visualizing various levels of data&#xff09; 《Python数据分析技术栈》第03章 03 可视化各级数据&#xff08;Visualizing various levels of data&#xff09; Whenever you need to analyze data, first understand if the data is stru…

Node.JS CreateWriteStream(大容量写入文件流优化)

Why I Need Node.JS Stream 如果你的程序收到以下错误&#xff0c;或者需要大容量写入很多内容(几十几百MB甚至GB级别)&#xff0c;则必须使用Stream文件流甚至更高级的技术。 Error: EMFILE, too many open files 业务场景&#xff0c;我们有一个IntradayMissingRecord的补…