文章目錄
- 前言
- 一、存儲 Bean
- 1, 配置文件
- 2, 五大類注解
- Bean 的命名規則
- 3, 方法注解
- Bean 的命名規則
- 二、獲取 Bean
- 1, 屬性注入
- 2, Setter 注入
- 3, 構造方法注入
- 4, @Autowired 和 @Resource 的區別
- 5, 同一個類型的多個 Bean 注入問題
- 總結
前言
各位讀者好, 我是小陳, 這是我的個人主頁, 希望我的專欄能夠幫助到你:
📕 JavaSE基礎: 基礎語法, 類和對象, 封裝繼承多態, 接口, 綜合小練習圖書管理系統等
📗 Java數據結構: 順序表, 鏈表, 堆, 二叉樹, 二叉搜索樹, 哈希表等
📘 JavaEE初階: 多線程, 網絡編程, TCP/IP協議, HTTP協議, Tomcat, Servlet, Linux, JVM等(正在持續更新)
Spring 中有很多注解
, 來幫助我們更加方便, 高效的編寫代碼, 本篇介紹存儲和獲取 Bean 時使用到的注解
提示:是正在努力進步的小菜鳥一只,如有大佬發現文章欠佳之處歡迎批評指點~ 廢話不多說,直接上干貨!
一、存儲 Bean
上篇文章 介紹了基本的存儲和獲取 Bean 的方式, 如果按照上篇文章介紹的方式存儲Bean, 那么每存儲一個 Bean 就需要在配置文件中寫一行標簽, 十分麻煩, 其實有一種更方便的方式, 我們可以配置存儲對象的掃描包路徑, 只有被配置的包下的所有類, 并且添加了注解 才能被正確的識別并保存到 Spring 中
1, 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:content="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><content:component-scan base-package="com"></content:component-scan>
</beans>
- resources 目錄下新建一個 .xml 文件, 把上述代碼拷貝到其中
指定了要掃描的包之后, 只有這個包, 以及這個包下面的子包中的代碼, 添加了注解之后才能生效
2, 五大類注解
類注解(加在類上的注解)有五個:@Controller、@Service、@Repository、@Component、@Configuration
-
使用 @Controller, 新建一個 UserController 類
-
使用 @Service, 新建一個 UserService 類
-
使用 @Repository, 新建一個 UserRepository 類
-
使用 @Component, 新建一個 UserComponent 類
-
使用 @Configuration, 新建一個 UserConfiguration 類
-
在啟動類中使用 ApplicationContext 獲取上下文對象, 使用 getBean 方法獲取并使用剛剛存儲的五個 Bean
-
觀察執行結果, 是否都成功的存儲了
綜上, 使用這五個類注解確實可以更方便的存儲 Bean, 不需要再每存儲一個就寫一行配置標簽, 那為什么要有五個呢? 一個不夠嗎? 這些注解有什么作用?
這五個注解分別標識了不同的作用, 看到這個注解就知道這個類是用來干什么的 :
@Controller 標識了業務邏輯層
@Service 標識了服務層
@Repository 標識了持久層
@Component 標識了組件層
@Configuration 標識了配置層
以下是阿里的工程分層調用流程 :
在真實的項目中也是需要按照大致的流程來分層管理代碼模塊
Bean 的命名規則
我們只是在配置文件中指定了要掃描的包路徑, 并沒有指定要存儲的 Bean 的名稱, 那憑什么根據下面代碼中標出的這些命名就能正確找到 Bean 呢?
-
默認情況下, Bean 的名稱就是類名的小駝峰形式, 比如 : 類名是
UserController
, Bean 的名稱默認就是userController
-
但是!!! 如果類名的第一個字母和第二個字母都是大寫, 比如:
ABC
, 那么 Bean 的名稱就是ABC(原類名) 而不是 aBC
如果 Bean 的名稱是 aBC 無法存儲
如果 Bean 的名稱是 ABC 可以存儲
所以只有 不滿足類名的前兩個字母都是大寫 的情況下, Bean 的默認命名是小駝峰形式, 否則就是原類名
當然也可以手動命名, 這些類注解都可以設置一個 Value 參數, 如圖 :
3, 方法注解
方法注解 @Bean 是修飾在一個方法上, 那怎么能存儲 Bean(類對象) 呢? 其實是把方法最終返回的對象存儲起來, 且 @Bean 必須搭配五大類注解之一使用, 且一定要有返回值
- 先定義一個 User 類
- 使用 @Bean 存儲方法最終返回的 Bean 對象
- 獲取并使用 Bean
Bean 的命名規則
-
使用方法注解存儲的 Bean, 默認名稱就是 @Bean 注解所加的方法名而不再是類名, (一個類中可能有多個方法需要使用 @Bean, 如果仍然使用類名作為默認命名, 可能多個 Bean 會重名)
-
也可以給 @Bean 注解傳遞參數來設定名字, 甚至可以設置一個數組, 其中包含多個名字
獲取 Bean 對象時使用這兩個名字都可以
-
如果多個 @Bean 注解命名相同, 只有一個 Bean 能被存儲
如果多個 @Bean 使用相同的名稱, 例如上述 : 喜羊羊這個 Bean 先被加載, 所以先使用了 user 這個名字, 美羊羊這個 Bean 后被加載, 也想用 user 這個名字, 卻被檢查到 user 這個名字已經有人用了, 就不存儲美羊羊這個 Bean 了
在 @Bean 中重命名之后, 就不能使用默認的命名了
二、獲取 Bean
獲取 Bean 對象也叫對象裝配, 是把對象取出來放到某個類中,有時候也叫對象注?
對象注入有三種方式 : 屬性注入, Setter 注入, 構造方法注入, 都是使用 @Autowired 注解來實現
按照實際開發的模式, 將 Repository 類注入到 Service 類中, Repository 類的實現如下:
當前代碼以及接下來的代碼都會放在dome4這個包下面, 配置文件中也要設置這個包的掃描路徑
1, 屬性注入
這是開發中最常用的方式, 因為代碼簡潔方便
加了 @Autowired 注解 之后, 就會將已經存儲過的 UserRepository 這個類型的 Bean 注入進來
通過屬性注入的方式, 就可以獲取到這個 Bean 并使用它的方法
2, Setter 注入
3, 構造方法注入
構造方法注入是 Spring 推薦的方式
構造方法注入更符合單一設計的原則, 因為構造方法只會隨著類的加載而調用一次, 不會被任意修改和調用, 也可以保證在使用這個被注入的對象時能被完全初始化, 也可以注入被 final 修飾的變量
4, @Autowired 和 @Resource 的區別
@Autowired 注解也可以被 @Resource 注解代替, 區別如下 :
- 出身不同:@Autowired 來自于 Spring,而 @Resource 來自于 JDK 的注解;
- 使?時設置的參數不同:相比于 @Autowired 來說,@Resource 支持更多的參數設置,例如 name 設置,根據名稱獲取 Bean。
- @Autowired 可用于 Setter 注入、構造函數注入和屬性注入,而 @Resource ,不能?于構造函數注入
5, 同一個類型的多個 Bean 注入問題
- 先定義一個 User 類, 提供 setter 和 toString 方法
- 在 Users 類中使用方法注解存儲兩個類型為 User 的 Bean, 并設置屬性的值
- 在 Service 層注入 User, 查看 User 的值
- 在 APP 啟動類中調用 showUser 這個方法, 觀察結果
程序執行的結果一定是報錯, 因為我們存儲了兩個類型為 User 的 Bean , 在使用 @Autowired 注入時, 是首先根據 User 這個類型進行匹配, 發現找到了兩個 Bean , 于是程序就不能確定到底要注入哪一個了
@Autowired 注入時, 首先根據類型進行匹配, 如果多個 Bean 類型相同, 再根據 Bean 的名稱進行注入
- 解決方案一 : 存儲 Bean 時設置好名稱, 注入時再明確指定名稱
- 解決方案二 : 使用 @Autowired 搭配 @Qualifier 注解指定注入的 Bean 的名稱
這個 @Qualifier 注解更像是加了一層篩選操作
- 解決方案三 : 使用 @Resource 注解指定 name
使用上述任意三種方式都可以正確的拿到想要的 Bean :
總結
以上就是本篇的所有內容了:
- 使用 @Controller、@Service、@Repository、@Component、@Configuration 這五大類注解可以存儲 Bean, 在注解中設置一個 Value 參數對 Bean 重命名
- 使用 @Bean 這個方法注解并搭配
任意一個類注解
可以將返回值作為 Bean 存儲, 在注解中可以指定一個或多個字符串對 Bean 重命名 - 使用 @Autowired 可以進行屬性注入, setter 注入, 構造方法注入, 實現方便的獲取 Bean
如果本篇對你有幫助,請點贊收藏支持一下,小手一抖就是對作者莫大的鼓勵啦😋😋😋~
上山總比下山辛苦
下篇文章見