Spring -- DI

文章目錄

  • 一、什么是DI
  • 二、注入的三種方式
    • 2.1 屬性注入 @Autowired
      • 使用方法
      • @Autowired存在的問題以及解決方法
      • @Autowired問題的解決方法
    • 2.2 構造方法注入
    • 2.3 setter方法注入
    • 2.4 三種注入方式優缺點分析

一、什么是DI

  1. 概念:DI(依賴注入)就是當我們把依賴對象取出來(創建好后),賦值給該對象的屬性
  2. DI的其他翻譯:屬性裝配、依賴裝配

二、注入的三種方式

注入只是去拿,但是有沒有,是要依靠【Spring實現的loC的方式】

2.1 屬性注入 @Autowired

使用方法

  1. @Autowired 作用:告訴Spring我們需要這個對象,去loC容器里拿
  2. @Autowired 注入原則
    • 在注入時,是根據類型去注入的
    • 如果一個類型存在多個對象時,優先名稱匹配,如果名稱都匹配不上,就會報錯。
@Controller
public class TestController {@Autowiredprivate UserService userService;public void doController(){userService.doService();System.out.println("這是Controoler注解");}
}@Service
public class UserService {public void doService(){System.out.println("這是Service注解");}
}
  1. 關于報錯:因為@Autowired不是官方推薦寫法,所以IDEA可能會報錯。但即便如此,由于操作簡單,使用量依舊很高
  2. 使用Debug查看當前變量的值:Debug狀態下,選中某個變量,選擇“Evaluate Expression……”可以進行數值模擬

@Autowired存在的問題以及解決方法

因為構造方法注入和Setter注入都是依據@Autowired實現的,所以它們也存在下面的問題

  1. 有多個類型時要根據名稱去拿,有報錯的風險
  2. 沒有辦法去注入一個由final修飾的屬性:因為final是不可變的,要求是在定義期間或初始化期間給其賦值
  3. 使用量太高了,可能會濫用
  4. 違反了軟件設計的單一原則

@Autowired問題的解決方法

【1】方法介紹

  1. 讓屬性名和你需要的對象名稱一致:這樣@Autowired就可以根據名稱匹配

  2. 如果不想保持一致:使用@Primary、@Qualifier

    • @Primary:標識默認的對象
    • @Qualifier:指定要使用的Bean名稱
      • 既然@Autowired沒辦法加上屬性名,我們就用其他的注解來給其加上屬性名
    • @Resource:通過描述bean的信息,去指定要用哪個
  3. 重命名Bean

  4. @Autowird VS @Resource

    • 提供者不同:ctrl或選中注解就可以出現該注解的相關信息,點擊小圓球可以定位包。rt是jdk的包。
      • @Autowired 是Spring框架提供的注解,而@Resource是JDK提供的注解
    • 注入方式
      • @Autowired 默認是按照類型注入,如果同一個類型存在多個,再按照名稱匹配,如果名稱匹配不上,就會報錯
      • @Resource 支持更多的參數設置,例如 name 設置,可以根據名稱獲取 Bean

【2】方法的具體使用

  1. 使用@Primary
@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfoZ(){UserInfo userInfo = new UserInfo();userInfo.setUsername("zhangsan");userInfo.setPassword("123456");return userInfo;}@Primary@Beanpublic UserInfo userInfoL(){UserInfo userInfo = new UserInfo();userInfo.setUsername("lisi");userInfo.setPassword("123456");return userInfo;}}@Controller
public class TestController {@Autowiredprivate UserInfo userInfo;public void doController(){System.out.println(userInfo); //lisi}
}
  1. 使用@Qualifier
@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfoZ(){UserInfo userInfo = new UserInfo();userInfo.setUsername("zhangsan");userInfo.setPassword("123456");return userInfo;}@Beanpublic UserInfo userInfoL(){UserInfo userInfo = new UserInfo();userInfo.setUsername("lisi");userInfo.setPassword("123456");return userInfo;}}@Controller
public class TestController {@Qualifier("userInfoZ")@Autowiredprivate UserInfo userInfo;public void doController(){System.out.println(userInfo); //zhangsan}
}
  1. 使用@Resource
@Configuration
public class BeanConfig {@Beanpublic UserInfo userInfoZ(){UserInfo userInfo = new UserInfo();userInfo.setUsername("zhangsan");userInfo.setPassword("123456");return userInfo;}@Beanpublic UserInfo userInfoW(String nameW){UserInfo userInfo = new UserInfo();userInfo.setUsername(nameW);userInfo.setPassword("123456");return userInfo;}@Beanpublic String nameW(){return "wangwu";}}@Controller
public class TestController {@Resource(name = "userInfoW")@Autowiredprivate UserInfo userInfo;public void doController(){System.out.println(userInfo);  //wangwu}
}
  1. 重命名Bean
@Configuration
public class BeanConfig {@Bean("u1")public UserInfo userInfoZ(){UserInfo userInfo = new UserInfo();userInfo.setUsername("zhangsan");userInfo.setPassword("123456");return userInfo;}@Beanpublic UserInfo userInfoL(){UserInfo userInfo = new UserInfo();userInfo.setUsername("lisi");userInfo.setPassword("123456");return userInfo;}}@Controller
public class TestController {@Autowiredprivate UserInfo u1;public void doController(){System.out.println(u1); //zhangsan}
}

2.2 構造方法注入

  1. 構造函數的創建問題
    • 當我們新增了屬性時,可能就要去新加上構造方法,十分繁瑣
    • 當我們添加了有參的構造函數,就不會默認生成無參的構造函數了,如果需要用無參的,就需要手動生成
  2. @Autowired 指定用哪個構造函數:當有多個構造函數且沒有指定用哪個時,Spring去初始化就會不知道用哪個,可能會報錯
    • 如果有無參構造函數,默認用無參的,此時userService為null
    • 如果沒有無參構造函數,我們需要用@Autowired告訴Spring使用哪個構造函數。當然,如果只有一個構造函數時,@Autowired是可以省略的
@Controller
public class TestController {private UserService userService;@Autowiredpublic TestController(UserService userService) {this.userService = userService;}public TestController() {}public void doController(){userService.doService();System.out.println("這是Controoler注解");}
}@Service
public class UserService {public void doService(){System.out.println("這是Service注解");}
}

2.3 setter方法注入

@Controller
public class TestController {private UserService userService;@Autowired    //需要加上,不加會報錯public void setUserService(UserService userService) {this.userService = userService;}public void doController(){userService.doService();System.out.println("這是Controoler注解");}
}

2.4 三種注入方式優缺點分析

  1. 屬性注入:雖然不被官方推薦,但因為簡單,程序員推薦使用
    • 優點: 簡潔,使用方便
    • 缺點:
      • @Autowired是Spring提供的,只能在Spring這使用
      • 不能注入?個Final修飾的屬性
  2. 構造函數注?(Spring 4.X推薦)
    • 優點:
      • 符合final可以在構造方法中賦值的設定,故而可以注入final修飾的屬性
      • 注入的對象不會被修改。因為構造函數是在創建對象的時候執行的,執行完之后除非再創建一個對象,或者使用Setter注入,否則不會輕易被改變。
      • 依賴對象在使用前?定會被完全初始化,因為依賴是在類的構造方法中執行的,而構造方法是在類加載階段就會執行的方法
      • 通用性好, 構造方法是JDK支持的,即使是更換任何框架,他都是適用的
    • 缺點:注入多個對象時, 代碼會比較繁瑣,還需要用@Autowired指定
  3. Setter注入(Spring 3.X推薦):事實上,當一個對象需要被修改,我們就沒必要交給Spring管理了,直接自己new一個算了
    • 優點:方便在類實例之后, 重新對該對象進行配置或者注入
    • 缺點:
      • 不能注入?個Final修飾的屬性
      • 注入對象可能會被改變, 因為setter方法可能會被多次調用, 就有被修改的風險。你能改別人也能改,代碼就會很亂。

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

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

相關文章

以太坊錢包

以太坊錢包是你通往以太坊系統的門戶。它擁有你的密鑰,并且可以代表你創建和廣播交易。選擇一個以太坊錢包可能很困難,因為有很多不同功能和設計選擇。有些更適合初學者,有些更適合專家。即使你現在選擇一個你喜歡的,你可能會決定…

mac m1 pcre.h 找不到

安裝suricata報錯: configure: error: pcre.h not found ... 解決: brew install pcre 找到這個文件的地址 brew list pcre | grep pcre.h$ /opt/homebrew/Cellar/pcre/8.45/include/pcre.h 程序搜索的地址 cpp -v /Library/Developer/CommandLineT…

5.26 基于UDP的網絡聊天室

需求&#xff1a; 如果有人發送消息&#xff0c;其他用戶可以收到這個人的群聊信息 如果有人下線&#xff0c;其他用戶可以收到這個人的下線信息 服務器可以發送系統信息實現模型 模型&#xff1a; 代碼&#xff1a; //chatser.c -- 服務器端實現 #include <stdio.h>…

hive初始化失敗報錯:Error: Duplicate key name ‘PCS_STATS_IDX‘ (state=42000,code=1061)

意思是key name ‘PCS_STATS_IDX’ (state42000,code1061)重復了&#xff0c;問題出在不是第一次初始化&#xff0c;因為我們在hive-site.xml中配置了 javax.jdo.option.ConnectionURL jdbc:mysql://192.168.200.137:3306/metastore?createDatabaseIfNotExisttrue JDBC conne…

JavaSE——類和對象(二)~~封裝

目錄 一.封裝 二.封裝擴展之包 三.static成員 四. 代碼塊 五. 內部類&#xff08;重要&#xff09; 大家好呀&#xff0c;我是北緯&#xff0c;接著上節我們繼續講解Java中關于類和對象的相關知識&#xff0c;今天著重給大家介紹一下關于面向對象程序的特性之一——封裝。…

【Linux】常用基礎命令 | 搭建云服務器優化環境 | 程序的部署

文章目錄 Linux常用命令及搭建環境一、LinuxLinux發行版 1.常用命令1.ls2.cd3.pwd4.touch5.cat6.echo7.vim8.mkdir9.rm10.mv11.cp12.man13.grep14.ps15.netstat 2.搭建Java Web程序的運行環境包管理器1.安裝JDK2.安裝Tomcat3.安裝mysql 3.程序的部署 Linux常用命令及搭建環境 …

貪心算法簡單介紹

貪心算法是一種在每一步選擇中都采取當前狀態下最優或最優近似的選擇&#xff0c;以期望最終得到全局最優解的算法。貪心算法并不總能得到全局最優解&#xff0c;但在某些問題上&#xff0c;它可以得到全局最優解&#xff0c;并且比動態規劃等其他方法更為簡單和高效。 貪心算…

Python庫之Scrapy的簡介、安裝、使用方法詳細攻略

Python庫之Scrapy的簡介、安裝、使用方法詳細攻略 簡介 Scrapy是一個快速的、高層次的web抓取和web抓取框架&#xff0c;用于抓取網站數據并從頁面中提取結構化的數據。Scrapy用途廣泛&#xff0c;可以用于數據挖掘、信息處理或存儲歷史數據&#xff0c;以及各種其他用途。 …

【AMS】Android 8.0+ 繞開啟動后臺Service限制

一、背景 應客戶要求,需要在開機時,拉起應用A。但因為開機時,同時被拉起的應用過多,導致Launcher在開機那一刻較為卡頓。為解決這一問題,采取了延遲拉起的做法。在開機后,延遲一定時間,由系統服務,拉起應用A。 于是乎,就出現這么個報錯: Not allowed to start ser…

vue3、vuex和vue-router入門指南

Vue 3、Vuex 和 Vue Router 都是 Vue.js 生態系統中非常有用的庫。它們各自在 Vue.js 應用程序中扮演著重要的角色&#xff1a;Vue 3 是核心框架&#xff0c;Vuex 用于狀態管理&#xff0c;而 Vue Router 用于路由管理。下面是如何在 Vue 3 項目中使用這些庫的簡要說明。 創建…

有趣的css - 移形換位加載動畫

大家好&#xff0c;我是 Just&#xff0c;這里是「設計師工作日常」&#xff0c;今天分享的是一個移形換位動態加載小動效&#xff0c;適用于 app 列表加載&#xff0c;頁面加載或者圖片懶加載等場景。 最新文章通過公眾號「設計師工作日常」發布。 目錄 整體效果核心代碼html…

2024上海初中生古詩文大會倒計時4個月:單選題真題解析(持續)

現在距離2024年初中生古詩文大會還有4個多月時間&#xff0c;我們繼續來看10道選擇題真題和詳細解析&#xff0c;以下題目截取自我獨家制作的在線真題集&#xff0c;都是來自于歷屆真題&#xff0c;去重、合并后&#xff0c;每道題都有參考答案和解析。 為幫助孩子自測和練習&…

C#基礎一

使用Visual Studio 2022&#xff08;VS2022&#xff09;編寫C#控制臺程序 1. 安裝Visual Studio 2022 確保已安裝Visual Studio 2022。如果未安裝&#xff0c;請從Visual Studio官網下載并安裝。 另一篇文章中已經有詳細描述&#xff0c;這里就不在細說了。 VisualStudio2022…

【LeetCode】【209】長度最小的子數組(1488字)

文章目錄 [toc]題目描述樣例輸入輸出與解釋樣例1樣例2樣例3 提示進階Python實現前綴和二分查找滑動窗口 個人主頁&#xff1a;丷從心 系列專欄&#xff1a;LeetCode 刷題指南&#xff1a;LeetCode刷題指南 題目描述 給定一個含有n個正整數的數組和一個正整數target找出該數組…

Effective C++(2)

文章目錄 2. 構造、析構、賦值運算條款05&#xff1a;了解C默默編寫并調用哪些函數條款06&#xff1a;若不想使用編譯器自動生成的函數&#xff0c;就該明確拒絕條款07&#xff1a;為多態基類聲明virtual析構函數條款08&#xff1a;別讓異常逃離析構函數條款09&#xff1a;絕不…

微信小程序報錯:notifyBLECharacteristicValueChange:fail:nodescriptor的解決辦法

文章目錄 一、發現問題二、分析問題二、解決問題 一、發現問題 微信小程序報錯&#xff1a;notifyBLECharacteristicValueChange:fail:nodescriptor 二、分析問題 這個提示有點問題&#xff0c;應該是該Characteristic的Descriptor有問題&#xff0c;而不能說nodescriptor。 …

web前端之解決img元素組件自有高度的問題

MENU 前言解決辦法vertical-align 前言 在HTML和CSS中&#xff0c;img元素默認是行內元素(inline element)&#xff0c;類似于文本。由于文本有基線(baseline)&#xff0c;所以即使是空白的img元素也會占據一定的高度&#xff0c;以便使基線對齊。 解決辦法 要解決這個問題&…

axios如何傳遞數組作為參數,后端又如何接收呢????

前端的參數是一個數組。 前端編寫&#xff1a; 后端接收&#xff1a;

Iterater迭代器和增強for循環

1、Collection接口遍歷元素—Iterator迭代器 看一下下面這張圖片&#xff1a;可以看出Collection接口有一個父接口Iterable&#xff0c;Iterable接口有一個iterator()方法&#xff0c;iterator()方法的類型是Iterator迭代器&#xff0c;實際上當我們使用方法時&#xff0c;返回…

Go語言的pprof工具是如何使用的?

文章目錄 Go語言的pprof工具詳解pprof的使用runtime/pprofnet/http/pprof 快速開始獲取采樣數據通過pprof工具進行性能分析總結 Go語言的pprof工具詳解 Go語言作為一個高性能、高并發的編程語言&#xff0c;對性能優化有著極高的要求。在Go語言的標準庫中&#xff0c;pprof是一…