java面試題,什么是動態代理?、動態代理和靜態代理有什么區別?說一下反射機制?JDK Proxy 和 CGLib 有什么區別?動態代理的底層

什么是動態代理?

動態代理是在程序運行期,動態的創建目標對象的代理對象,并對目標對象中的方法進行功能性增強的一種技術。

在生成代理對象的過程中,目標對象不變,代理對象中的方法是目標對象方法的增強方法。可以理解為運行期間,對象中方法的動態攔截,在攔截方法的前后執行功能操作。

動態代理的常見使用場景有:

  1. 統計每個 api 的請求耗時;
  2. 統一的日志輸出;
  3. 校驗被調用的 api 是否已經登錄和權限鑒定;
  4. Spring AOP。

動態代理和靜態代理有什么區別?

靜態代理其實就是事先寫好代理類,可以手工編寫也可以使用工具生成,但它的缺點是每個業務類都要對應一個代理類,特別不靈活也不方便。

動態代理是在程序運行期,動態的創建目標對象的代理對象,并對目標對象中的方法進行功能性增強的一種技術。

所以總結來說,動態代理和靜態代理的效果都是一樣的,但靜態代理使用麻煩,而動態代理使用簡單,后者也是現在編程中實現代理的主流方式。

如何實現動態代理?

在 Java 中,實現動態代理的常用方式是 JDK Proxy 和 CGLib。

JDK Proxy 和 CGLib 有什么區別?

JDK Proxy 和 CGLib 的區別主要體現在以下幾個方面:

  1. JDK Proxy 是 Java 語言自帶的功能,無需通過加載第三方類實現;
  2. Java 對 JDK Proxy 提供了穩定的支持,并且會持續的升級和更新 JDK Proxy,例如 Java 8 版本中的 JDK Proxy 性能相比于之前版本提升了很多;
  3. JDK Proxy 是通過攔截器加反射的方式實現的;
  4. JDK Proxy 只能代理繼承接口的類;
  5. JDK Proxy 實現和調用起來比較簡單;
  6. CGLib 是第三方提供的工具,基于 ASM 實現的,性能比較高;
  7. CGLib 無需通過接口來實現,它是通過實現子類的方式來完成調用的。

動態代理的底層是如何實現的?

不同的動態代理的底層實現是不同的,比如 JDK Proxy 底層是通過反射技術實現的,而 CGLib 是基于 ASM,一個 Java 字節碼操作框架實現的。

說一下反射機制?

Java 反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為 Java 語言的反射機制。簡單來說,反射機制指的是程序在運行時能夠獲取自身的信息。在 Java 中,只要給定類的名字,就可以通過反射機制來獲得類的所有信息。

Java 反射機制主要提供了以下功能,這些功能都位于 java.lang.reflect 包:

  1. 在運行時判斷任意一個對象所屬的類;
  2. 在運行時構造任意一個類的對象;
  3. 在運行時判斷任意一個類所具有的成員變量和方法;
  4. 在運行時調用任意一個對象的方法;
  5. 生成動態代理。

在程序開發中反射的使用場景有很多,比如以下幾個。

使用場景一:編程工具 IDEA 或 Eclipse 等,在寫代碼時會有代碼(屬性或方法名)提示,就是因為使用了反射;

使用場景二:很多知名的框架,如 Spring、MyBatis 等,為了讓程序更優雅更簡潔,也會使用到反射。

例如,Spring 可以通過配置來加載不同的類,調用不同的方法,代碼如下所示:

<bean id="person" class="com.spring.beans.Person" init-method="initPerson">
</bean>

例如,MyBatis 在 Mapper 使用外部類的 Sql 構建查詢時,代碼如下所示:

@SelectProvider(type = PersonSql.class, method = "getListSql")
List<Person> getList();
class PersonSql {public String getListSql() {String sql = new SQL() {{SELECT("*");FROM("person");}}.toString();return sql;}
}

使用場景三:數據庫連接池,也會使用反射調用不同類型的數據庫驅動,代碼如下所示:

String url = "jdbc:mysql://127.0.0.1:3306/mydb";
String username = "root";
String password = "root";
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(url, username, password);

如何使用反射?

在 Java 中,反射獲取調用類可以通過 Class.forName(),反射獲取類實例要通過 newInstance(),相當于 new 一個新對象,反射獲取方法要通過 getMethod(),獲取到類方法之后使用 invoke() 對類方法進行調用。如果是類方法為私有方法的話,則需要通過 setAccessible(true) 來修改方法的訪問限制,以上的這些操作就是反射的基本使用,具體調用如下。

  • 反射調用靜態方法
Class myClass = Class.forName("類名");
Method method = myClass.getMethod("調用方法名");
method.invoke(myClass);
  • 反射調用公共方法
Class myClass = Class.forName("類名");
// 創建實例對象(相當于 new )
Object instance = myClass.newInstance();
Method method2 = myClass.getMethod("調用方法名");
method2.invoke(instance);
  • 反射調用私有方法
Class myClass = Class.forName("類名");
// 創建實例對象(相當于 new )
Object object = myClass.newInstance();
Method method3 = myClass.getDeclaredMethod("調用方法名");
method3.setAccessible(true);
method3.invoke(object);

反射有什么優缺點?

優點:

  1. 能夠運行時動態獲取類的實例,大大提高系統的靈活性和擴展性;
  2. 與 Java 動態編譯相結合,可以實現無比強大的功能;
  3. 對于 Java 這種先編譯再運行的語言,能夠讓我們很方便的創建靈活的代碼,這些代碼可以在運行時裝配,無需在組件之間進行源代碼的鏈接,更加容易實現面向對象。

缺點:

  1. 反射會消耗一定的系統資源,因此,如果不需要動態地創建一個對象,那么就不需要用反射;
  2. 反射調用方法時可以忽略權限檢查,獲取這個類的私有方法和屬性,因此可能會破壞類的封裝性而導致安全問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/898349.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/898349.shtml
英文地址,請注明出處:http://en.pswp.cn/news/898349.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【工具類】Java的 LocalDate 獲取本月第一天和最后一天

博主介紹&#xff1a;?全網粉絲22W&#xff0c;CSDN博客專家、Java領域優質創作者&#xff0c;掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域? 技術范圍&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大數據、物…

嵌入式開發之STM32學習筆記day06

基于STM32F103C8T6的開發實踐——從入門到精通01 1. 引言 STM32系列微控制器是STMicroelectronics推出的一款高性能、低功耗的32位微控制器&#xff0c;廣泛應用于嵌入式系統中。STM32F103C8T6是其中非常受歡迎的一款&#xff0c;憑借其強大的性能、豐富的外設接口和低廉的價格…

學習使用 Git 和 GitHub 開發項目的教程推薦

Git 和 GitHub 是現代軟件開發中不可或缺的工具&#xff0c;無論你是個人開發者還是團隊成員&#xff0c;掌握它們都能極大提升效率。本文精選了一系列優質教程資源&#xff0c;涵蓋從基本 Git 命令到進階多人協作的內容。這些教程既有文字形式&#xff0c;也有視頻或交互式資源…

golang中的接口

1.簡介 在go中的接口是以一種類型,一種抽象的類型。接口(interface)是一組函數method的集合,go中的接口不能包含任何變量。在go中接口中的所有方法都沒有方法體,接口定義了一個對象的行為規范,只定義規范不實現。接口體現了程序的多態和高內聚低耦合的思想。go中的接口也是…

AI 浪潮下,職場的變與不變

如今&#xff0c;AI 如迅猛颶風&#xff0c;極速席卷職場&#xff0c;徹底攪亂了原有的秩序。你是否留意到&#xff0c;身邊的工作方式正悄然生變&#xff1f;今天&#xff0c;【探星 AI 研習社】就為大家深入剖析&#xff0c;AI 如何改寫職場劇本。無論你是大學生還是職場資深…

匯川EASY系列之以太網通訊(MODBUS_TCP做主站)

匯川Easy系列以太網通訊中(MODBUSTCP,plc做主站),終于可以不用使用指令就可以完成了,全程通過簡單的配置就可通訊。本文將通過EASY系列PLC與調試助手之間完成此操作。具體演示如下; 關于主站和從站的介紹 A/請求:即主動方 向被動方發送的一個要求的信息。 B/主站:發…

npm error gyp info

在使用 npm 安裝 Node.js 包時&#xff0c;可能會遇到各種錯誤&#xff0c;其中 gyp 錯誤是比較常見的一種。gyp 是 Node.js 的一個工具&#xff0c;用于編譯 C 代碼。這些錯誤通常發生在需要編譯原生模塊的 npm 包時。下面是一些常見的原因和解決方法&#xff1a; 常見原因及…

Oracle 19C分區表索引小結

一、大佬說&#xff08;楊廷琨&#xff09; LOCAL索引的最大好處是在進行分區操作&#xff0c;比如TRUNCATE PARTITION, DROP PARTITION時&#xff0c;不會出現索引INVALID的情況&#xff0c;不影響索引的可用性。由于GLOBAL索引所有的數據存儲在一起&#xff0c;因此當執行分…

AutoHub場景演示|帶您領略智能自動化操作的全新體驗

AutoHub是一款由OpenCSG推出的基于前沿大型語言模型&#xff08;LLM&#xff09;的瀏覽器自動化工具&#xff0c;旨在通過智能對話交互和自動化技術&#xff0c;幫助用戶更高效地瀏覽網頁和完成任務。它不僅能夠自動化繁瑣的網頁操作&#xff0c;還能夠為用戶提供精準的信息檢索…

深入解析 Linux 聲卡驅動:從架構到實戰

在嵌入式 Linux 設備中&#xff0c;音頻功能的實現離不開 Linux 聲卡驅動。而 ALSA (Advanced Linux Sound Architecture) 作為 Linux 內核的音頻框架&#xff0c;提供了一整套 API 和驅動模型&#xff0c;幫助開發者快速集成音頻功能。本篇文章以 WM8960 音頻編解碼器&#xf…

thinkphp5模型查詢數據庫,查出來的字段直接修改成另外的名字

在ThinkPHP5中,如果你希望在查詢數據庫時將返回的字段名直接修改為其他名稱,可以通過以下幾種方式實現: 方法1:使用 field 方法指定字段別名 在查詢時通過 field 方法直接為字段指定別名(使用 AS 關鍵字)。 示例代碼: // 使用Db類查詢 $result = Db::name(user)->…

關于前端指令

在前端開發中&#xff0c;指令&#xff08;Directives&#xff09;通常指在框架中使用的一種特殊的語法或機制&#xff0c;用于擴展 HTML 的功能。常見的指令主要存在于前端框架中&#xff0c;如 Vue.js、Angular 等。下面我們將分別介紹 Vue.js 和 Angular 中的常用指令&#…

虛擬地址空間(下)進程地址空間(上)

一.關于頁表組成 1.權限&#xff08;rwx) 作用&#xff1a;如1.讓代碼區變成只讀的 2.寫時拷貝的實現&#xff1a;子進程創建時其頁表指向的父進程代碼和數據權限都是只讀的&#xff0c;子進程試圖修改&#xff0c;觸發錯誤&#xff0c;系統開始寫時拷貝。 來源&#xff1a;…

【區塊鏈 + 航運物流】豐溯 - 區塊鏈溯源平臺 | FISCO BCOS 應用案例

豐溯是順豐科技推出的區塊鏈溯源平臺&#xff0c; 采用 FISCO BCOS 底層開源框架&#xff0c; 為農副食品、 冷鏈生鮮等企業客戶及消費 者提供關鍵流通節點的溯源信息服務&#xff0c;形成從源頭到消費者端全鏈路透明的信息鏈。 在商貿消費領域&#xff0c; 溯源一直是保障產品…

iwebsec-SQL數字型注入

1.判斷是否存在漏洞 添加and 11發現正常顯示&#xff0c;添加and 12無回顯條目&#xff0c;則存在sql注入漏洞 2.因為有回顯&#xff0c;嘗試union聯合注入&#xff0c;使用order by判斷出有3個字段 3.使用union聯合注入查看回顯位&#xff0c;發現3三個字段均有回顯&#xff…

藍橋杯每日五題第一日

藍橋杯每日5題 問題一 班級活動 1.班級活動 - 藍橋云課 問題描述 小明的老師準備組織一次班級活動。班上一共有 nn 名 (nn 為偶數) 同學&#xff0c;老師想把所有的同學進行分組&#xff0c;每兩名同學一組。為了公平&#xff0c;老師給每名同學隨機分配了一個 nn 以內的正…

STM32 —— 嵌入式系統、通用計算機系統、物聯網三層架構

目錄 一、嵌入式系統的概念 二、通用計算機系統與嵌入式系統的比較 用途 硬件 軟件 性能與功耗 開發與維護 三、嵌入式系統與物聯網的關系 四、物聯網的三層架構 1. 感知層&#xff08;Perception Layer&#xff09; 2. 網絡層&#xff08;Network Layer&#xff09; …

卡碼網25題——掌握ACM輸入輸出方式(15 至 18)

刷題小記&#xff1a; 本期涉及ACM模式下棧和鏈表的構建與使用&#xff0c;值得學習。 卡瑪網15.神秘字符&#xff08;卡瑪網15.神秘字符&#xff09; 題目分析&#xff1a; 若給定2行字符串&#xff0c;其中第一個串的長度為偶數&#xff0c;現要求把第二個串插入到第一個…

前端字段名和后端不一致?解鎖 JSON 映射的“隱藏規則” !!!

&#x1f680; 前端字段名和后端不一致&#xff1f;解鎖 JSON 映射的“隱藏規則” &#x1f31f; 嘿&#xff0c;技術冒險家們&#xff01;&#x1f44b; 今天我們要聊一個開發中常見的“坑”&#xff1a;前端傳來的 JSON 參數字段名和后端對象字段名不一致&#xff0c;會發生…

python中使用單例模式在整個程序中只創建一個數據庫連接,節省資源

示例代碼&#xff1a; from loguru import logger from pymongo import MongoClient from pymongo.errors import ConnectionFailurefrom llm_engineering.settings import settingsclass MongoDatabaseConnector:_instance: MongoClient | None Nonedef __new__(cls, *args,…