Spring IOC 和 AOP

Spring IOC

什么是 IoC ?

IoC (Inversion of Control 控制反轉)是一種設計思想,而不是一個具體的技術實現。IoC 的思想就是將原本在程序中手動創建對象的控制權,交由給 Spring 框架來管理

為什么叫控制反轉?

  • 控制:指的是對象的創建(實例化,管理)的權利
  • 反轉:控制權交給外部環境(Spring 框架、Ioc 容器)

????????將對象之間的相互依賴關系交給 IoC 容器來管理,并由 IoC 容器來完成對象的注入。這樣可以很大程度上簡化應用的開發,并做到解耦合,把應用從復雜的依賴關系中抽取出來,開發人員只需要關注對象的使用,而不需要關心對象是如何創建的。

? ? ? ? 在實際項目中,一個 Service 類可能依賴很多其他的類。假如我們需要實例化這個 Service ,每次都需要搞清楚這個 Service 所有底層類的構造函數。如果使用 IoC的話,只需要配置好Bean ,在需要的地方注入就行了,大大降低了項目的可維護性和開發難度。

什么是 Spring Bean?

可以簡單地理解為 Bean 指代的就是那些 被 IoC 容器所管理的對象。一般在 Spring Boot 中使用以下幾種注解聲明:

  • Component : 通用注解,可以標注任意類為 Spring 組件。如果一個類不清楚分在那一層,可使用 @Component 注解標注
  • @Repository:對應持久層 即 Dao 層,主要用于數據庫相關操作
  • @Service:對應服務層,主要設計一些復雜的邏輯處理
  • @Controller:對應 控制層 , 主要用于接收用戶的請求并調用 Service。


IoC 和 DI 有什么區別?

IoC 可以理解為以中國控制反轉的設計思想,而 DI 可以理解為這種設計思想的具體實現方式

IoC 解決了什么問題?

  1. 對象之間的耦合度降低
  2. 資源管理變得容易

例如,一個針對 User 的操作,利用 Service 和 Dao 層進行開發

在沒有使用 IoC 思想的情況下,Service 層想要使用 Dao 層的話,需要通過 new 關鍵字在 UserServiceImpl 中手動 new 一個 UserDao 的具體實現類 UserDaoImpl

但是,如果開發過程中出現新的需求,針對 UserDao 接口 開發出另一個 具體的實現類。由于 Service 層依賴了 UserDao 的具體實現,所以我們需要修改 UserServiceImpl 中 new 的對象。這就導致,如果我們的項目中很多地方都依賴于 UserDao 的實現類的話,就需要修改每一處,這就導致維護起來非常麻煩。

使用 IoC 的思想,我們將對象的控制權交給 Spring 容器管理后,我們在使用的時候直接向 IoC 容器 “要” 就行了。


Spring AOP

什么是 AOP?

AOP(Aspect Oriented Programming)即面向切面編程。

AOP 的目的是將橫切關注點(例如日志管理、事務管理、權限控制、接口控制)從核心業務邏輯中分離出來,通過動態代理,字節碼操作等技術,實現代碼的復用和解耦,提高代碼的可維護性和可擴展性。

OOP(面向對象編程)

AOP 和 OOP 其實并不沖突,兩者互補

OOP的目的是將業務邏輯按照對象的屬性和行為進行封裝,通過類、對象、繼承、多態等概念,實現代碼的模塊化和層次化,提高代碼的可讀性和可維護性

AOP 為什么叫面向切面編程?

因為 AOP 的核心思想是將橫切關注點從核心業務邏輯中分離出來,形成一個一個的切面。

  • 橫切關注點:多個類或對象中的公共行為(如日志記錄、事務管理、權限控制、接口限流等)
  • 切面(Aspect):對橫切關注點進行封裝的類,一個切面是一個類。切面可以定義多個通知,用來實現具體的功能
  • 連接點(JoinPoint):連接點是方法調用或方法執行時的某個特定時刻(如方法調用、拋出異常等)
  • 通知(Advice):通知就是切面在某個連接點要執行的操作。通知有五種類型分別是:前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、異常通知(AfterThrowing)和 環繞通知(Around)。
  • 切點(Pointcut):一個切點是一個表達式,它用來匹配哪些連接點需要被切面所增強。切點可以通過注解、正則表達式、邏輯運算等方式來定義。比如?execution(* com.xyz.service..*(..))匹配?com.xyz.service?包及其子包下的類或接口。
  • 織入(Weaving):織入是將切面和目標對象連接起來的過程,也就是將通知應用到切點匹配的連接點上。常見的織入時機有兩種,分別是編譯期織入(AspectJ)和運行期織入(AspectJ)

使用示例

AOP解決了什么問題?

OOP不能很好的處理一些分散在多個類或對象中的公共行為,這些行為通常被稱為 橫切關注點 。如果我們在每個類或者對象中都重復實現這些行為就會導致代碼的冗余、復雜和難以維護。

AOP 可以將橫切關注點 從 核心業務邏輯 中分離出來,實現關注點的分離。

比如說日志記錄,記錄每次訪問請求的參數和信息:


@Aspect
@Slf4j
@Component
@Order(0)
public class AopLog {private static final String START_TIME = "request-start";/***切入點* */@Pointcut("execution( * com.whgcdx.demo1.controller..*Controller.*(..))")public void log(){}/*** 環繞操作*/@Around("log()")public Object aroundLog(ProceedingJoinPoint point) throws Throwable {Object result = point.proceed();log.info("【返回值】:{}", JSON.toJSONString(result));return result;}/**** 前置操作*/@Before("log()")public void beforeLog(JoinPoint point){//利用 RequestContextHolder 獲取 HttpServletRequest 對象ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();UserAgent userAgent = UserAgentUtil.parse(httpServletRequest.getHeader(Header.USER_AGENT.toString()));//重組請求信息StringBuffer sb = new StringBuffer();sb.append("---------------------------------收到請求-------------------------------------------");sb.append("\r\n【瀏覽器類型】: " + userAgent.getBrowser() + " 【版本號】: " + userAgent.getVersion());sb.append("\r\n【user-agent】: " + httpServletRequest.getHeader(Header.USER_AGENT.toString()));sb.append("\r\n【訪問URL】: " + httpServletRequest.getRequestURI());sb.append("\r\n【訪問Method】: " + httpServletRequest.getMethod());sb.append("\r\n【訪問IP】: " + httpServletRequest.getRemoteAddr());sb.append("\r\n【訪問類名】:"+ point.getSignature().getDeclaringTypeName() + ", 【訪問方法名】:" + point.getSignature().getName());Map<String ,String[]> paramerMap = httpServletRequest.getParameterMap();sb.append("\r\n【請求參數】: " + paramerMap);log.info(sb.toString());httpServletRequest.setAttribute(START_TIME,System.currentTimeMillis());}/*****/@After("log()")public void afterLog(){ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();Long start= (Long) request.getAttribute(START_TIME);Long end=System.currentTimeMillis();log.info("【請求耗時】:{}ms",end-start);String header=request.getHeader(Header.USER_AGENT.toString());UserAgent userAgent=UserAgentUtil.parse(header);log.info("【操作系統】:{},【原始User-Agent】:{}",userAgent.getOs().toString(),header);}}

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

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

相關文章

unsigned詳講(干貨滿滿)

前言&#xff1a;過年偷懶了(●ˇ?ˇ●)&#xff0c;但是年后開學了一定要恢復學習狀態&#xff0c;在復習加繼續學習的途中&#xff0c;我發現對于unsigned關鍵字的掌握并不是很熟練&#xff0c;于是翻閱了各個大佬的博客以及書籍&#xff0c;總結了對于unsigned的一些知識點…

數據結構與算法編程題18

循環隊列相關代碼。 #include <iostream> using namespace std;#define Maxsize 100 #define ERROR 0 #define OK 1 typedef int Elemtype; typedef struct Queue {Elemtype data[Maxsize];int front;int rear; }Queue;void Init_Queue(Queue &Q) {Q.front Q.rear …

P9 C++類

目錄 01 類是什么 02 如何創建類 03 方法 后話 本期我們要講的是 C 中的類。 我們終于講到了面向對象編程&#xff0c;這是一種非常流行的編程方式&#xff0c;面向對象編程實際上只是一種你可以采用的編寫代碼的方式&#xff0c;其他語言例如 C#、Java 這些主要是面向對象…

白嫖CTG4.0

大家好&#xff0c;到點了我來給各位大佬獻策CTG&#xff0c;不是花錢買不起&#xff0c;而是免費更有性價比&#xff0c;哈哈哈不調侃了我們自此開始正文&#xff0c;咱們主打的就是一個分享是一種態度 當然我更希望大家支持國產對國產有自己的信心&#xff08;文心一言&…

Git常用命令詳細總結,更適合中國寶寶體質

文章目錄 代碼倉庫創建倉庫1.進入需要創建代碼庫的文件夾2.創建/切始化倉庫3.關聯遠程倉庫拉取遠程倉庫到本地 添加文件到倉庫1.查看工作區狀態2.添加文件到暫存區3.提交到本地倉庫4.對比工作區文件變化 倉庫配置1.配置全局用戶名和郵箱2.配當前倉庫用戶名和郵箱3.查看Git全局配…

Selenium中常用的JS操作總結

? 目錄 前言&#xff1a; JS相關操作 JS Xpath定位 獲取單個元素 獲取元素集合 文本輸入 獲取坐標 獲取瀏覽器窗口的內部高度 獲取瀏覽器窗口的內部寬度&#xff1b; 坐標計算 設置樣式 設置窗口大小 類數組對象arguments JQuery選擇器 jQuery 選擇器 jQuery …

多模態——使用stable-video-diffusion將圖片生成視頻

多模態——使用stable-video-diffusion將圖片生成視頻 0. 內容簡介1. 運行環境2. 模型下載3. 代碼梳理3.1 修改yaml文件中的svd路徑3.2 修改DeepFloyDataFiltering的vit路徑3.3 修改open_clip的clip路徑3.4 代碼總體結構 4. 資源消耗5. 效果預覽 0. 內容簡介 近期&#xff0c;…

Linux上安裝Redis

案例中Linux版本為CentOS7.9&#xff0c;安裝目錄為 /root/software/ 1、使用 wget 命令從官網下載安裝包 wget https://github.com/redis/redis/archive/7.2.3.tar.gz2、解壓縮 tar -xzf 7.2.3.tar.gz3、進入解壓后的目錄 cd redis-7.2.34、 編譯和安裝Redis make make i…

npm中,你不了解的.npmrc文件

原文鏈接&#xff1a;npm中&#xff0c;你不了解的.npmrc文件 寫在前面 對于寫JS的程序員來說&#xff0c;可能沒有人不知道npm&#xff0c;但是有些同學對他的配置文件(即.npmrc文件)并不了解。結合我的學習心得&#xff0c;寫一篇博客跟大家分享一些該配置文件的知識。 .np…

理解CLIP模型

1.簡介 學習深度學習必看CLIP&#xff01;論文鏈接arxiv.org/pdf/2103.00020v1.pdf。 簡單來說就是傳統的分類任務被用來預測指定的類別&#xff0c;有監督訓練限制了模型的通用性和可用性&#xff0c;并且需要帶有標簽的數據來訓練&#xff0c;該篇論文就想直接從原始文本中…

Navicat 技術指引 | 適用于 GaussDB 的用戶權限設置

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持對 GaussDB 主備版的管理和開發功能。它不僅具備輕松、便捷的可視化數據查看和編輯功能&#xff0c;還提供強大的高階功能&#xff08;如模型、結構同步、協同合作、數據遷移等&#xff09;&#xff0c;這…

Spring 七大組件

文章目錄 Spring 七大組件 Spring 七大組件 核心容器(Spring core) 核心容器提供Spring框架的基本功能。Spring以bean的方式組織和管理Java應用中的各個組件及其關系。Spring使用BeanFactory來產生和管理Bean&#xff0c;它是工廠模式的實現。BeanFactory使用控制反轉(IOC)模式…

(Matalb分類預測)GA-BP遺傳算法優化BP神經網絡的多維分類預測

目錄 一、程序及算法內容介紹&#xff1a; 基本內容&#xff1a; 亮點與優勢&#xff1a; 二、實際運行效果&#xff1a; 三、部分代碼&#xff1a; 四、本文代碼數據說明手冊分享 一、程序及算法內容介紹&#xff1a; 基本內容&#xff1a; 本代碼基于Matalb平臺編譯&am…

Flink Flink中的分流

一、什么是分流 所謂“分流”&#xff0c;就是將一條數據流拆分成完全獨立的兩條、甚至多條流。也就是基于一個DataStream&#xff0c;定義一些篩選條件&#xff0c;將符合條件的數據揀選出來放到對應的流里。 二、基于filter算子的簡單實現分流 其實根據條件篩選數據的需求…

面了一個4年經驗的測試工程師,自動化都不會也要15k,我也是醉了····

&#x1f4e2;專注于分享軟件測試干貨內容&#xff0c;歡迎點贊 &#x1f44d; 收藏 ?留言 &#x1f4dd; 如有錯誤敬請指正&#xff01;&#x1f4e2;交流討論&#xff1a;歡迎加入我們一起學習&#xff01;&#x1f4e2;資源分享&#xff1a;耗時200小時精選的「軟件測試」資…

表單考勤簽到作業周期打卡打分評價評分小程序開源版開發

表單考勤簽到作業周期打卡打分評價評分小程序開源版開發 表單打卡評分 表單簽到功能&#xff1a;學生可以通過掃描二維碼或輸入簽到碼進行簽到&#xff0c;方便教師進行考勤管理。 考勤功能&#xff1a;可以記錄學生的出勤情況&#xff0c;并自動生成出勤率和缺勤次數等統計數…

本地緩存與分布式緩存

一、緩存的概念 在服務端編程當中&#xff0c;緩存主要是指將數據庫的數據加載到內存中&#xff0c;之后對該數據的訪問都在內存中完成&#xff0c;從而減少了對數據庫的訪問&#xff0c;解決了高并發場景中數據庫容易成為性能瓶頸的問題&#xff1b;以及基于內存的訪問速度高…

ruoyi-plus-vue部署

安裝虛擬機 部署文檔 安裝docker 安裝docker 安裝docker-compose 可能遇到的錯誤 Failed to deploy ruoyi/ruoyi-server:5.1.0 Dockerfile: ruoyi-admin/Dockerfile: Cant retrieve im age ID from build stream 安裝 vim 命令 yum install vim -y 修改文件 vim /etc/re…

flutter 無法從H5 WebView 訪問攝像頭和錄音權限

AndroidManifest.xml需要在 中添加以下權限&#xff1a; <uses-permission android:name"android.permission.INTERNET"/> <uses-permission android:name"android.permission.CAMERA" /> <uses-permission android:name"android.per…

基于Springboot的冬奧會科普平臺(有報告),Javaee項目,springboot項目。

演示視頻&#xff1a; 基于Springboot的冬奧會科普平臺&#xff08;有報告&#xff09;&#xff0c;Javaee項目&#xff0c;springboot項目。 項目介紹&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三層…