深入解析 Spring IOC AOP:原理、源碼與實戰

深入解析 Spring IOC & AOP:原理、源碼與實戰

Spring 框架的核心在于 IOC(控制反轉)AOP(面向切面編程)。今天,我們將深入剖析它們的原理,結合源碼解析,并通過 Java 代碼實戰來掌握這兩個核心概念。


📌 1. 什么是 IOC(控制反轉)?

IOC(Inversion of Control)是 Spring 的核心思想,它將對象的創建和依賴關系的管理交給 Spring 容器,避免了傳統的 new 關鍵字實例化方式。

🔥 1.1 IOC 機制

Spring 使用 BeanFactoryApplicationContext 管理 Bean 的生命周期,主要流程如下:

  1. 讀取配置(XML 或注解)
  2. 實例化 Bean(通過 BeanFactory
  3. 依賴注入(通過 @Autowired
  4. Bean 生命周期管理

📌 2. 手寫簡易 IOC 容器

我們用 Java 代碼手寫一個簡化版的 IOC 容器,模擬 Spring 依賴注入的實現。

📝 代碼示例:

import java.util.HashMap;
import java.util.Map;// 模擬 Spring 容器
class SimpleIOC {private Map<String, Object> beanContainer = new HashMap<>();// 注冊 Beanpublic void registerBean(String name, Object obj) {beanContainer.put(name, obj);}// 獲取 Beanpublic Object getBean(String name) {return beanContainer.get(name);}
}// 測試 IOC 容器
class UserService {public void sayHello() {System.out.println("Hello, Spring IOC!");}
}public class TestIOC {public static void main(String[] args) {SimpleIOC ioc = new SimpleIOC();ioc.registerBean("userService", new UserService());UserService userService = (UserService) ioc.getBean("userService");userService.sayHello();}
}

🔍 運行結果

Hello, Spring IOC!

? 分析

  • SimpleIOC 充當 Spring 容器,存儲和管理 Bean 實例。
  • registerBean() 方法模擬 ApplicationContext 注冊 Bean 的功能。
  • getBean() 方法模擬 getBean(Class<T> clazz) 獲取對象。

📌 3. 什么是 AOP(面向切面編程)?

AOP(Aspect-Oriented Programming)通過 動態代理 在方法執行前后加入額外邏輯,常用于 日志、事務、權限控制 等場景。

🔥 3.1 AOP 機制

Spring AOP 主要通過 JDK 動態代理(基于接口)和 CGLIB(基于子類)實現。

📖 3.2 Spring AOP 代理模式

Spring AOP 主要使用 代理模式,在目標方法執行前后執行增強邏輯,如:

  • @Before(前置通知)
  • @AfterReturning(后置通知)
  • @Around(環繞通知)

📌 4. 手寫 AOP 代理(JDK 動態代理)

我們使用 JDK 動態代理 實現 AOP,模擬 Spring @Transactional 事務管理。

📝 代碼示例:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 業務接口
interface UserService {void createUser();
}// 業務實現類
class UserServiceImpl implements UserService {public void createUser() {System.out.println("創建用戶...");}
}// AOP 代理類
class AOPProxy implements InvocationHandler {private Object target;public AOPProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("開啟事務...");Object result = method.invoke(target, args);System.out.println("提交事務...");return result;}// 生成代理對象public static Object getProxy(Object target) {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new AOPProxy(target));}
}// 測試 AOP 代理
public class TestAOP {public static void main(String[] args) {UserService userService = new UserServiceImpl();UserService proxyService = (UserService) AOPProxy.getProxy(userService);proxyService.createUser();}
}

🔍 運行結果

開啟事務...
創建用戶...
提交事務...

? 分析

  • AOPProxy 通過 JDK 動態代理 在方法調用前后加入事務邏輯。
  • getProxy() 生成代理對象,并攔截 UserService 的方法調用。
  • 運行后,createUser() 方法被代理增強,實現 AOP 事務管理功能。

📌 5. Spring AOP 實戰(@Aspect)

在 Spring 中,我們可以使用 @Aspect@Around 注解實現 AOP 事務管理。

📝 代碼示例:

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Aspect
@Component
public class TransactionAspect {@Before("execution(* com.service.*.*(..))")public void beginTransaction() {System.out.println("開啟事務...");}@After("execution(* com.service.*.*(..))")public void commitTransaction() {System.out.println("提交事務...");}
}

🌟 關鍵點

  • @Aspect:聲明 AOP 切面類
  • @Before / @After:在方法執行前/后執行事務邏輯
  • execution(* com.service.*.*(..)):匹配 com.service 包下的所有方法

📌 6. 總結

功能Spring 機制手寫代碼
IOC依賴注入(DI)手寫 BeanFactory
AOP事務管理、日志JDK 動態代理
Spring AOP@Aspect 切面@Before@After

? 今日收獲

  • 理解了 IOC 機制,并手寫 IOC 容器
  • 掌握了 AOP 代理機制,并手寫 JDK 動態代理
  • 結合 Spring @Aspect 注解,掌握 AOP 事務管理

🚀 明日預告:Spring MVC 深度解析(DispatcherServlet、HandlerMapping、攔截器)

🔗 學習資料
📖 Spring 官方文檔


💬 你對 Spring IOC & AOP 有什么疑問?歡迎留言交流! 🚀

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

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

相關文章

LLM之RAG理論(十四)| RAG 最佳實踐

RAG 的過程很復雜&#xff0c;包含許多組成部分。我們如何確定現有的 RAG 方法及其最佳組合&#xff0c;以確定最佳 RAG 實踐&#xff1f; 論文 《Searching for Best Practices in Retrieval-Augmented Generation》給出了回答。 本文將從以下三方面進行介紹&#xff1a; 首先…

利用knn算法實現手寫數字分類

利用knn算法實現手寫數字分類 1.作者介紹2.KNN算法2.1KNN&#xff08;K-Nearest Neighbors&#xff09;算法核心思想2.2KNN算法的工作流程2.3優缺點2.4 KNN算法圖示介紹 3.實驗過程3.1安裝所需庫3.2 MNIST數據集3.3 導入手寫數字圖像進行分類3.4 完整代碼3.5 實驗結果 1.作者介…

C語言-適配器模式詳解與實踐

文章目錄 C語言適配器模式詳解與實踐1. 什么是適配器模式&#xff1f;2. 為什么需要適配器模式&#xff1f;3. 實際應用場景4. 代碼實現4.1 UML 關系圖4.2 頭文件 (sensor_adapter.h)4.3 實現文件 (sensor_adapter.c)4.4 使用示例 (main.c) 5. 代碼分析5.1 關鍵設計點5.2 實現特…

Rust函數、條件語句、循環

文章目錄 函數**語句與表達式**條件語句循環 函數 Rust的函數基本形式是這樣的 fn a_func(a: i32) -> i32 {}函數名是蛇形風格&#xff0c;rust不在意函數的聲明順序&#xff0c;只需要有聲明即可 函數參數必須聲明參數名稱和類型 語句與表達式 這是rust非常重要的基礎…

maptalks圖層交互 - 模擬 Tooltip

maptalks圖層交互 - 模擬 Tooltip 圖層交互-模擬tooltip官方文檔 <!DOCTYPE html> <html><meta charsetUTF-8 /><meta nameviewport contentwidthdevice-width, initial-scale1 /><title>圖層交互 - 模擬 Tooltip</title><style typet…

好吧好吧,看一下達夢的模式與用戶的關系

單憑個人感覺&#xff0c;模式在達夢中屬于邏輯對象合集&#xff0c;回頭再看資料 應該是一個用戶可以對應多個模式 問題來了&#xff0c;模式的ID和用戶的ID一樣嗎&#xff1f; 不一樣 SELECT USER_ID,USERNAME FROM DBA_USERS WHERE USERNAMETEST1; SELECT ID AS SCHID, NA…

python socket模塊學習記錄

python黑馬程序員 通過python內置socket模塊&#xff0c;在電腦本地開發一個服務器&#xff0c;一個客戶端&#xff0c;連接后進行連續的聊天。服務器和客戶端均可輸入exit&#xff0c;主動退出連接。 服務器開發.py import socket# 創建Socket對象 socket_server socket.s…

7-2 sdut-C語言實驗-逆序建立鏈表

7-2 sdut-C語言實驗-逆序建立鏈表 分數 20 全屏瀏覽 切換布局 作者 馬新娟 單位 山東理工大學 輸入整數個數N&#xff0c;再輸入N個整數&#xff0c;按照這些整數輸入的相反順序建立單鏈表&#xff0c;并依次遍歷輸出單鏈表的數據。 輸入格式: 第一行輸入整數N;&#xff…

針對永磁電機(PMM)的d軸和q軸電流,考慮交叉耦合補償,設計P1控制器并推導出相應的傳遞函數

電流控制回路:針對永磁電機(PMM)的d軸和q軸電流&#xff0c;考慮交叉耦合補償&#xff0c;設計P1控制器并推導出相應的傳遞函數。 1. 永磁電機&#xff08;PMM&#xff09;的數學模型 在同步旋轉坐標系&#xff08; d ? q d - q d?q 坐標系&#xff09;下&#xff0c;永磁同…

ROS多機通信(四)——Ubuntu 網卡 Mesh 模式配置指南

引言 使用Ad-hoc加路由協議和直接Mesh模式配置網卡實現的網絡結構是一樣的&#xff0c;主要是看應用選擇&#xff0c; Ad-Hoc模式 B.A.T.M.A.N. / OLSR 優點&#xff1a;靈活性高&#xff0c;適合移動性強或需要優化的復雜網絡。 缺點&#xff1a;配置復雜&#xff0c;需手動…

chap1:統計學習方法概論

第1章 統計學習方法概論 文章目錄 第1章 統計學習方法概論前言章節目錄導讀 實現統計學習方法的步驟統計學習分類基本分類監督學習無監督學習強化學習 按模型分類概率模型與非概率模型 按算法分類按技巧分類貝葉斯學習核方法 統計學習方法三要素模型模型是什么? 策略損失函數與…

爬蟲案例-爬取某站視頻

文章目錄 1、下載FFmpeg2、爬取代碼3、效果圖 1、下載FFmpeg FFmpeg是一套可以用來記錄、轉換數字音頻、視頻&#xff0c;并能將其轉化為流的開源計算機程序。 點擊下載: ffmpeg 安裝并配置 FFmpeg 步驟&#xff1a; 1.下載 FFmpeg&#xff1a; 2.訪問 FFmpeg 官網。 3.選擇 Wi…

車載以太網網絡測試-22【傳輸層-DOIP協議-5】

目錄 1 摘要2 DoIP時間參數2.1 ISO 13400定義的時間參數2.2 參數示例 3 DoIP節點內部狀態機4 UDSonIP概述5 總結 1 摘要 本文繼續對DOIP協議進行介紹&#xff0c;主要是DOIP相關的時間參數、時間參數定義以及流程示例。推薦大家對上文專題進行回顧&#xff0c;有利于系統性學習…

(論文總結)思維鏈激發LLM推理能力

研究背景&動機 背景:擴大模型規模已被證實具有提升模型性能和模型效率的功效&#xff0c;但是LLM對于完成推理、算術任務仍有較大不足。 動機:從之前的應用和研究中得知&#xff0c;可以用生成自然語言解釋、使用神經符號等形式語言的方法來提高大模型的算術推理能力&…

前后端開發概述:架構、技術棧與未來趨勢

一、前后端開發的基本概念 1.1 什么是前后端開發&#xff1f; 前后端開發是 Web 開發的兩個核心部分&#xff0c;各自承擔不同的職責&#xff1a; 前端&#xff08;Frontend&#xff09; 負責網頁的用戶界面&#xff08;UI&#xff09;和用戶體驗&#xff08;UX&#xff09;…

anythingLLM結合searXNG實現聯網搜索

1、docker-compose 部署searXNG GitHub - searxng/searxng-docker: The docker-compose files for setting up a SearXNG instance with docker. cd /usr/local git clone https://github.com/searxng/searxng-docker.git cd searxng-docker 2、修改 .env文件 # By default…

人形機器人科普

人形機器人&#xff08;Humanoid Robot&#xff09;是一種模仿人類外形和行為的機器人&#xff0c;通常具有頭部、軀干、雙臂和雙腿等結構。它們的設計目標是與人類環境無縫交互&#xff0c;執行復雜的任務&#xff0c;甚至在某些領域替代人類工作。 1. 人形機器人的定義與特點…

【CICD】Ansible知識庫

一、主機清單配置 1. 配置文件路徑 默認路徑 /etc/ansible/hosts 這是 Ansible 的全局默認庫存文件路徑&#xff0c;但許多用戶可能不會直接使用它。項目目錄或自定義路徑 用戶通常會為不同項目創建獨立的庫存文件&#xff0c;例如&#xff1a; 當前目錄下的 hosts、inventor…

ArkUI-List組件

列表是一個復雜的容器&#xff0c;當列表項達到一定數量&#xff0c;使得列表內容超出其范圍的時候&#xff0c;就會自動變為可以滾動。列表適合用來展現同類數據類型。 List的基本使用方法 List組件的構建聲明是這個樣子的 List(value?: {space?:number | string, initial…

Ubuntu實時讀取音樂軟件的音頻流

文章目錄 一. 前言二. 開發環境三. 具體操作四. 實際效果 一. 前言 起因是這樣的&#xff0c;我需要在Ubuntu中&#xff0c;實時讀取正在播放音樂的音頻流&#xff0c;然后對音頻進行相關的處理。本來打算使用的PipewireHelvum的方式實現&#xff0c;好處是可以直接利用Helvum…