Java后端高頻面經——Spring、SpringBoot、MyBatis

  1. Spring定義一個Bean有哪些方法?依賴注入有哪些方法?

    (1)定義Bean的方法

    • 注解定義Bean,@Component

      用于標記一個類作為Spring的bean。當一個類被@Component注解標記時,Spring會將其實例化為一個bean,并將其添加到Spring容器中。

    • 配置文件定義Bean

    (2)依賴注入的方法

    • 字段(Field):最直接地在類的字段上使用。
    public class MyClass {@Autowiredprivate MyDependency myDependency;
    }
    
    • 構造器(Constructor):在構造器上使用,用于構造器注入。
    public class MyClass {private MyDependency myDependency;@Autowiredpublic MyClass(MyDependency myDependency) {this.myDependency = myDependency;}
    }
    
    • 方法(Method):也可以在一個方法上使用,通常是一個 setter 方法。
    public class MyClass {private MyDependency myDependency;@Autowiredpublic void setMyDependency(MyDependency myDependency) {this.myDependency = myDependency;}
    }
    
  2. 介紹IOC、AOP、反射

    (1)IOC

    ? Spring IOC容器通過

    ? ①封裝對象的創建(將對象的創建過程交給Spring管理,從而實現了控制反轉)和生命周期管理(管理對象的初始化和銷毀過程),

    ? ②使用依賴注入來解耦對象之間的依賴關系(通過 Spring 容器將類 A 所依賴的 B 的實例注入到 A 中,這樣 A 和 B 不再直接依賴,而是通過容器來提供),

    ? ③利用反射和配置元數據動態地創建和管理對象(當 Spring 容器啟動時,它會根據配置文件或注解(元數據)掃描類的信息,通過反射技術實例化對象,而不需要編寫具體的 new 代碼。反射讓 Spring 能夠動態地操作類的構造函數、方法等),

    ? ④同時提供作用域管理功能(對象的生命周期和可見性范圍。Spring 提供了多種作用域,容器會根據作用域來管理對象的實例化、銷毀等過程。Singleton(單例)、Prototype(原型)、Request、Session、Application 等作用域)。

    (2)AOP

    ? 面向切面編程,AOP能夠將那些與業務無關,卻為業務模塊所共同調用的邏輯(例如事務處理、日志管理、權限控制等)封裝起來,以減少系統的重復代碼,降低模塊間的耦合度。

    ? 兩個例子:權限校驗攔截器、動態切換數據源。

    ? Spring AOP的實現依賴于動態代理技術。動態代理是在運行時動態生成代理對象,而不是在編譯時。

    注解
    @Aspect用于定義切面,標注在切面類上。
    @Pointcut定義切點,標注在方法上,用于指定連接點。
    @Before在方法執行之前執行通知。
    @After在方法執行之后執行通知。
    @Around在方法執行前后都執行通知。

    (3)反射

    ? 允許在運行時動態地查詢和操作類、方法、字段等信息,并且能夠通過反射來調用類中的方法或修改類的屬性。反射機制的核心原理是:通過 Class 類來獲取類的結構信息,并且使用這些信息在運行時動態地操作類的對象。IOC、DI、動態代理就是用到了反射。

    ①獲取class對象:可以通過類的 Class 對象來訪問類的信息。

    Class<?> clazz = Class.forName("Person");  //括號里的內容可以是程序運行時才輸入的內容
    

    ②查詢類的結構信息:通過 Class 對象,可以獲取類的構造方法、方法、字段、接口、父類等信息。

    Method[] methods = clazz.getMethods(); // 獲取所有公共方法
    Field[] fields = clazz.getFields(); // 獲取所有公共字段
    Constructor[] constructors = clazz.getConstructors(); // 獲取所有公共構造函數
    

    ③動態創建對象

    Constructor<?> constructor = clazz.getConstructor(); // 獲取無參構造
    Object instance = constructor.newInstance(); // 使用構造函數創建對象實例
    

    ④調用方法

    Method method = clazz.getDeclaredMethod("myMethod", String.class);
    method.setAccessible(true);  // 如果是私有方法,需要設置訪問權限
    method.invoke(obj, "parameter");  // 調用方法
    
  3. 介紹動態代理、靜態代理?

    ? 代理模式是設計模式中的一種,它通過提供代理對象來控制對原對象的訪問。代理對象充當中介,通常在請求實際操作之前或之后做一些額外的工作(例如檢查權限、緩存結果、延遲加載等)。

    ? 控制訪問:代理可以控制對實際對象的訪問,增加額外的功能(如安全性、權限管理、日志記錄等)。

    ? 延遲加載:通過代理,可以延遲初始化或執行耗時的操作,直到真正需要時才執行。

    ? 性能優化:代理對象可以緩存結果,減少重復計算或請求,提高性能。

    ? 增強功能:代理對象可以在不修改原對象代碼的情況下,為其增加新的功能,如事務管理、日志記錄等。

    (1)動態代理

    動態代理是在運行時創建代理對象,代理對象在運行時被動態地生成,因此不需要在編譯時就確定代理類。Java 提供了兩種方式來實現動態代理:

    1. JDK 動態代理
      • 通過 java.lang.reflect.Proxy 類和 InvocationHandler 接口動態生成代理類。JDK 動態代理要求目標類實現一個接口
    2. CGLIB(Code Generation Library)代理
      • 通過字節碼生成技術,動態創建目標類的子類來實現代理。CGLIB 代理不要求目標類實現接口,而是通過繼承目標類來實現代理。

    (2)靜態代理

    ? 代理類是在編譯時就已經寫好并且確定的。是由開發者手動編寫的,并且在程序運行之前就已經存在。例如,你在編寫代碼時就知道你需要一個 Proxy 類,它會代理 RealSubject 類的方法。在靜態代理中,代理類和目標類的關系是固定的,編譯時就已經確定。

    ? 代理模式是JAVA的一種設計模式,而AOP是Spring框架中的一個特性,是使用了動態代理來實現的。

  4. Spring的循環依賴的原因以及解決方法;(眾安)

    循環依賴指的是兩個類中的屬性相互依賴對方:例如 A 類中有 B 屬性,B 類中有 A屬性,從而形成了一個依賴閉環。

    Spring中的循環依賴問題有三種情況:

    • 第一種:通過構造方法進行依賴注入時產生的循環依賴問題。
    • 第二種:通過setter方法進行依賴注入且是在多例(原型)模式下產生的循環依賴問題。
    • 第三種:通過setter方法進行依賴注入且是在單例模式下產生的循環依賴問題。

    單例模式適用于全局唯一的資源管理,如配置管理、日志記錄、數據庫連接池等。它的特點是保證類在全局范圍內只有一個實例,所有地方都使用同一個對象。

    多例模式適用于需要多個獨立實例的場景,如用戶會話、任務調度、訂單管理等。每個實例有自己的狀態和行為,不共享數據。

    只有【第三種方式】的循環依賴問題被 Spring 解決了,其他兩種方式在遇到循環依賴問題時,Spring都會產生異常。

    (1)Spring實例化Bean:Spring嘗試創建A的實例,發現A依賴B,因此需要實例化B。Spring在創建B時,發現B依賴A,但此時A還沒有完成初始化,所以Spring會創建A的空對象并將其放入singletonObjects一級緩存中并開始創建B。

    (3)循環依賴暴露

    • 當Spring嘗試創建B時,由于A還沒有完全初始化,Spring會把A實例(未完全初始化)提前暴露到earlySingletonObjects二級緩存中,這時A成為一個半初始化的Bean。
    • B可以通過earlySingletonObjects二級緩存獲得這個提前暴露的A對象,從而完成B的依賴注入。

    (3)初始化Bean

    • 依賴注入完成后,Spring繼續初始化B(如調用@PostConstruct等),然后將B放入三級singletonFactories緩存中,表示B已經完全初始化。

    • Spring繼續完成A的初始化工作,注入B,完成生命周期的其他部分,并將A放入三級singletonFactories緩存中,表示A也已經完全初始化。

    (4)總結

    • 在依賴注入過程中,Spring通過earlySingletonObjects二級緩存提供了B對A的依賴,通過singletonFactories三級緩存提供了A對B的依賴,從而打破了循環依賴。
  5. 列舉幾個Spring常用的注解?(美團)

    注解作用
    @Autowired自動裝配bean,當Spring容器中存在與要注入的屬性類型匹配的bean時,它會自動將bean注入到屬性中
    @ComponentSpring會將一個類實例化為一個bean,并將其添加到Spring容器中。
    @Configuration用于標記一個類作為Spring的配置類,配置類可以包含@Bean注解的方法,用于定義和配置bean,作為全局配置。
    @Bean用于標記一個方法作為Spring的bean工廠方法,當一個方法被@Bean注解標記時,Spring會將該方法的返回值作為一個bean,并將其添加到Spring容器中
    @Service用于標記服務層的bean,是@Component注解的特例,一般標記在業務service的實現類。
    @Repository用于標記數據訪問層的bean,它也是@Component注解的特例。
    @Controller用于標記控制層的bean,它也是@Component注解的特例。
  6. spring、springboot、SpringMVC的區別及關系?(康泰)

    Spring 是一個全面的應用開發框架,提供了全面的基礎設施和功能支持。

    Spring MVC 是 Spring 框架中的一個模塊,專門用于 Web 開發,采用 MVC 模式來處理 Web 請求和響應。它依賴于 Spring 框架的核心功能,如 IoC 和 AOP。

    Spring Boot 是一個基于 Spring 的項目,它封裝了 Spring 和其他相關技術(如 Spring MVC、Spring Data、Spring Security 等),提供自動配置、快速項目啟動器、內嵌服務器三大功能,使開發者能夠快速啟動和構建 Spring 應用。

    • 自動配置
    • 快速項目啟動器,通過引入不同的 Starter,可以快速集成常用的框架和庫(如數據庫、消息隊列、Web 開發等),極大地提高了開發效率。
    • 內嵌服務器(Tomcat、Jetty、Undertow),無需額外配置,即可將應用打包成可執行的 JAR 文件,方便部署和運行。

    Spring+Spring MVC = Spring Boot

  7. springboot的自動配置原理?(美團、得物)springBoot啟動機制,啟動之后做了哪些步驟?(B站)

  8. SpringBoot重要注解

    @SpringBootApplication用于標注主應用程序類,標識一個Spring Boot應用程序的入口點,同時啟用自動配置和組件掃描。
    @Controller標識控制器類,處理HTTP請求。
    @RestController結合@Controller和@ResponseBody,返回RESTful風格的數據。
    @Service標識服務類,通常用于標記業務邏輯層。
    @Repository標識數據訪問組件,通常用于標記數據訪問層。
    @Component通用的Spring組件注解,表示一個受Spring管理的組件。
    @Autowired用于自動裝配Spring Bean。
    @Value用于注入配置屬性值。
    @RequestMapping用于映射HTTP請求路徑到Controller的處理方法。
    @GetMapping、@PostMapping、@PutMapping、@DeleteMapping簡化@RequestMapping的GET、POST、PUT和DELETE請求。
    @Configuration用于指定一個類為配置類,其中定義的bean會被Spring容器管理。
  9. 怎么用原生的MyBatis去查詢?

    (1)配置MyBatis: 在配置文件中配置數據源、MyBatis的Mapper文件位置等信息。

    (2)創建實體類:創建與數據庫表對應的實體類,字段名和類型需與數據庫表保持一致。

    public class User {private Long id;private String username,private String email,// Getters and setters
    }
    

    (3)編寫SQL映射文件:在resources目錄下創建XML文件,定義SQL語句和映射關系。

    <mapper namespace="com.example.dao.UserMapper"><select id="selectUserById" resultType="com.example.model.User">SELECT * FROM users WHERE id = #{id}</select>
    </mapper>
    

    (4)編寫DAO接口:創建DAO接口,定義查詢方法。

    public interface UserMapper {User selectUserById(Long id);
    }
    

    (5)編寫具體的SQL查詢語句:在XML文件中編寫對應的SQL語句。

    (6)調用查詢方法:在服務層或控制層中調用DAO接口中的方法進行查詢。

    // 在Service層中調用
    User user = userMapper.selectUserById(1);
    
  10. MyBatis里的 # 和 $ 的區別?

  • Mybatis 在處理 #{}時,會創建預編譯的 SQL 語句,將 SQL 中的 #{} 替換為?號,在執行 SQL 時會為預編譯 SQL 中的占位符(?)賦值,調用 PreparedStatement 的 set 方法來賦值,預編譯的 SQL 語句執行效率高,并且可以防止SQL注入,提供更高的安全性,適合傳遞參數值。

  • Mybatis 在處理 ${} 時,只是創建普通的 SQL語句,然后在執行 SQL語句時 MvBatis 將參數直接拼入到 SQL里,不能防止 SQL注入,因為參數直接拼接到 SQL語句中,如果參數未經過驗證、過濾,可能會導致安全問題。

    比如:

    <select id="getUserByUsername" resultType="User">SELECT * FROM users WHERE username = '${username}'
    </select>
    

    在這個查詢中,${username} 會直接被傳入的 username 值替換,假如傳入的 username 是惡意的,例如 "' OR 1=1",查詢語句就變成了:

    SELECT * FROM users WHERE username = '' OR 1=1
    

    這就是典型的 SQL 注入,因為 $ 直接拼接了參數值,導致不安全的 SQL 被執行。

    大多數情況下都應該使用 #,特別是涉及到用戶輸入的值時。它可以安全地處理用戶輸入,避免 SQL 注入。只有在確實需要拼接動態 SQL 的結構部分(如表名、列名)時,才應該使用 $

  1. MybatisPlus和Mybatis的區別?(百度)

    MybatisPlus是一個基于MyBatis的增強工具庫。

    • CRUD操作:MybatisPlus通過繼承BaseMapper接口,提供了一系列內置的快捷方法,使得CRUD操作更加簡單,無需編寫重復的SQL語句。
    • 代碼生成器:MvbatisPlus提供了代碼生成器功能,可以根據數據庫表結構自動生成實體類、Mapper接口以及XML映射文件,減少了手動編寫的工作量。
    • 通用方法封裝:MybatisPlus封裝了許多常用的方法,如條件構造器、排序、分頁查詢等,簡化了開發過程,提高了開發效率。
    • 分頁插件:MybatisPlus內置了分頁插件,支持各種數據庫的分頁查詢,開發者可以輕松實現分頁功能,而在傳統的MyBatis中,需要開發者自己手動實現分頁邏輯。
    • 多租戶支持:MvbatisPlus提供了多租戶的支持,可以輕松實現多租戶數據隔離的功能。
    • 注解支持:MvbatisPlus引入了更多的注解支持,使得開發者可以通過注解來配置實體與數據庫表之間的映射關系,減少了XML配置文件的編寫。

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

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

相關文章

Qt 實現繪圖板(支持橡皮擦與 Ctrl+Z 撤銷功能)[特殊字符]

作業&#xff1a; 1&#xff1a;實現繪圖的時候&#xff0c;顏色的隨時調整 2&#xff1a;追加橡皮擦功能 3&#xff1a;配合鍵盤事件&#xff0c;實現功能 當鍵盤按 ctrlz的時候&#xff0c;撤銷最后一次繪圖 頭文件.h #ifndef WIDGET_H #define WIDGET_H#include <QWidge…

計算機網絡(1) 網絡通信基礎,協議介紹,通信框架

網絡結構模式 C/S-----客戶端和服務器 B/S -----瀏覽器服務器 MAC地址 每一個網卡都擁有獨一無二的48位串行號&#xff0c;也即MAC地址&#xff0c;也叫做物理地址、硬件地址或者是局域網地址 MAC地址表示為12個16進制數 如00-16-EA-AE-3C-40 &#xff08;每一個數可以用四個…

HOW - React 如何在在瀏覽器繪制之前同步執行 - useLayoutEffect

目錄 useEffect vs useLayoutEffectuseEffectuseLayoutEffect主要區別總結選擇建議注意事項 useLayoutEffect 使用示例測量 DOM 元素的尺寸和位置示例&#xff1a;自適應彈出框定位 同步更新樣式以避免閃爍示例&#xff1a;根據內容動態調整容器高度 圖像或 Canvas 繪制前的準備…

【無人機三維路徑規劃】基于CPO冠豪豬優化算法的無人機三維路徑規劃Maltab

代碼獲取基于CPO冠豪豬優化算法的無人機三維路徑規劃Maltab 基于CPO冠豪豬優化算法的無人機三維路徑規劃 一、CPO算法的基本原理與核心優勢 冠豪豬優化算法&#xff08;Crested Porcupine Optimizer, CPO&#xff09;是一種新型元啟發式算法&#xff0c;其靈感來源于冠豪豬的…

深度學習驅動的智能化革命:從技術突破到行業實踐

第一章 深度學習的技術演進與核心架構 1.1 從淺層網絡到深度學習的范式轉變 深度學習的核心在于通過多層次非線性變換自動提取數據特征,其發展歷程可劃分為三個階段:符號主義時代的規則驅動(1950s-1980s)、連接主義時代的淺層網絡(1990s-2000s)以及深度學習時代的端到端…

簡潔實用的3個免費wordpress主題

高端大氣動態炫酷的免費企業官網wordpress主題 非常簡潔的免費wordpress主題&#xff0c;安裝簡單、設置簡單&#xff0c;幾分鐘就可以搭建好一個wordpress網站。 經典風格的免費wordpress主題 免費下載 https://www.fuyefa.com/wordpress

RabbitMQ 高級特性解析:RabbitMQ 消息可靠性保障 (上)

RabbitMQ 核心功能 RabbitMQ 高級特性解析&#xff1a;RabbitMQ 消息可靠性保障 &#xff08;上&#xff09;-CSDN博客 RabbitMQ 高級特性&#xff1a;從 TTL 到消息分發的全面解析 &#xff08;下&#xff09;-CSDN博客 前言 最近再看 RabbitMQ&#xff0c;看了看自己之前寫…

用DeepSeek-R1-Distill-data-110k蒸餾中文數據集 微調Qwen2.5-7B-Instruct!

下載模型與數據 模型下載&#xff1a; huggingface&#xff1a; Qwen/Qwen2.5-7B-Instruct HF MirrorWe’re on a journey to advance and democratize artificial intelligence through open source and open science.https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct 魔搭&a…

在IDEA中進行git回滾操作:Reset current branch to here?或Reset HEAD

問題描述 1&#xff09;在本地修改好的代碼&#xff0c;commit到本地倉庫&#xff0c;突然發覺有問題不想push推到遠程倉庫了&#xff0c;但它一直在push的列表中存在&#xff0c;那該怎么去掉push列表中的內容呢&#xff1f; 2&#xff09;合并別的分支到當前分支&#xff0…

六十天前端強化訓練之第十一天之事件機制超詳解析

歡迎來到編程星辰海的博客講解 目錄 一、事件模型演進史 1.1 原始事件模型&#xff08;DOM Level 0&#xff09; 1.2 DOM Level 2事件模型 1.3 DOM Level 3事件模型 二、事件流深度剖析 2.1 捕獲與冒泡對比實驗 2.2 事件終止方法對比 三、事件委托高級應用 3.1 動態元…

Qwen架構與Llama架構的核心區別

我們在討論Deepseek不同版本之間的區別時了解到,DeepSeek-R1的蒸餾模型分為Qwen和Llama兩個系列,包括Qwen系列的0.5B、1.5B、3B、7B、14B、32B、72B和Llama系列的8B、70B。Qwen系列以阿里通義千問(Qwen)為基礎模型架構(具體是Qwen-2.5),Llama系列以Meta的Llama為基礎模型…

匿名GitHub鏈接使用教程(Anonymous GitHub)2025

Anonymous GitHub 1. 引言2. 準備3. 進入Anonymous GitHub官網4. 用GitHub登錄匿名GitHub并授權5. 進入個人中心&#xff0c;然后點擊? Anonymize Repo實例化6. 輸入你的GitHub鏈接7. 填寫匿名鏈接的基礎信息8. 提交9. 實例化對應匿名GitHub鏈接10. 進入個人中心管理項目11. 查…

工程化與框架系列(25)--低代碼平臺開發

低代碼平臺開發 &#x1f527; 引言 低代碼開發平臺是一種通過可視化配置和少量代碼實現應用開發的技術方案。本文將深入探討低代碼平臺的設計與實現&#xff0c;包括可視化編輯器、組件系統、數據流管理等關鍵主題&#xff0c;幫助開發者構建高效的低代碼開發平臺。 低代碼…

Redis系列之慢查詢分析與調優

Redis 慢查詢分析與優化&#xff1a;提升性能的實戰指南 Redis 作為一款高性能的內存數據庫&#xff0c;因其快速的數據讀寫能力和靈活的數據結構&#xff0c;被廣泛應用于緩存、消息隊列、排行榜等多種業務場景。然而&#xff0c;隨著業務規模的擴大和數據量的增加&#xff0…

Git系列之git tag和ReleaseMilestone

以下是關于 Git Tag、Release 和 Milestone 的深度融合內容&#xff0c;并補充了關于 Git Tag 的所有命令、詳細解釋和指令實例&#xff0c;條理清晰&#xff0c;結合實際使用場景和案例。 1. Git Tag 1.1 定義 ? Tag 是 Git 中用于標記特定提交&#xff08;commit&#xf…

開源項目介紹:Native-LLM-for-Android

項目地址&#xff1a;Native-LLM-for-Android 創作活動時間&#xff1a;2025年 支持在 Android 設備上運行大型語言模型 &#xff08;LLM&#xff09; &#xff0c;具體支持的模型包括&#xff1a; DeepSeek-R1-Distill-Qwen: 1.5B Qwen2.5-Instruct: 0.5B, 1.5B Qwen2/2.5VL:…

深入理解 Java 虛擬機內存區域

Java 虛擬機&#xff08;JVM&#xff09;是 Java 程序運行的核心環境&#xff0c;它通過內存管理為程序提供高效的執行支持。JVM 在運行時將內存劃分為多個區域&#xff0c;每個區域都有特定的作用和生命周期。本文將詳細介紹 JVM 的運行時數據區域及其功能&#xff0c;并探討與…

PDF轉JPG(并去除多余的白邊)

首先&#xff0c;手動下載一個軟件&#xff08;poppler for Windows&#xff09;&#xff0c;下載地址&#xff1a;https://github.com/oschwartz10612/poppler-windows/releases/tag/v24.08.0-0 否則會出現以下錯誤&#xff1a; PDFInfoNotInstalledError: Unable to get pag…

深入剖析MyBatis緩存機制:原理、源碼與實戰指南

引言 MyBatis作為一款優秀的ORM框架,其緩存機制能顯著提升數據庫查詢性能。但許多開發者僅停留在“知道有緩存”的層面,對其實現原理和細節知之甚少。本文將結合可運行的代碼示例和源碼分析,手把手帶您徹底掌握MyBatis緩存機制。 一、MyBatis緩存分類 MyBatis提供兩級緩存…

Vue 使用 vue-router 時,多級嵌套路由緩存問題處理

Vue 使用 vue-router 時&#xff0c;多級嵌套路由緩存問題處理 對于三級菜單&#xff08;或多級嵌套路由&#xff09;&#xff0c;vue 都是 通過 keep-alive 組件來實現路由組件的緩存。 有時候三級或者多級路由時&#xff0c;會出現失效情況。以下是三級菜單緩存的例子。 最…