關(guān)于 Spring 的創(chuàng)建及簡(jiǎn)單的使用
可以參考這篇文章
??Spring—存儲(chǔ)Bean
之前的存儲(chǔ)方式是利用<bean id="" class=""></bean>
進(jìn)行存儲(chǔ)
但這種方式存在一個(gè)弊端
即需要存儲(chǔ)的 Bean 過(guò)多時(shí), 手動(dòng)添加過(guò)于繁瑣
利用注解可以有效規(guī)避這種情況
- 添加注解存儲(chǔ) Bean
- 類注解
- @Controller: 控制器存儲(chǔ)
- @Service: 服務(wù)存儲(chǔ)
- @Repository: 倉(cāng)庫(kù)存儲(chǔ)
- @Component: 組件存儲(chǔ)
- @Configuration: 配置存儲(chǔ)
- 方法注解
- @Bean: 對(duì)象存儲(chǔ)(需搭配類注解一同使用)
- 類注解
配置掃描路徑
添加如下代碼至xml
文件中
<content:component-scan base-package=""></content:component-scan>
base-package=""
引號(hào)中填寫(xiě)的是掃描路徑
完整代碼
<?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=""></content:component-scan>
</beans>
如圖base-package="com.demo"
掃描路徑為com
包下的demo
包下的全部
所有的類都寫(xiě)在 Java 根路徑下, 沒(méi)有目錄, 該如何存儲(chǔ) / 獲取 Bean??
(了解即可, 通常不會(huì)這么做)
base-package="**"
將掃描路徑更改為根目錄下的全部
*
表示根目錄**
表示根目錄下的全部
利用類注解進(jìn)行存儲(chǔ)
在 Spring Core 中, 類注解之間的區(qū)別不大
添加注解存儲(chǔ)Bean
添加 @Controller 注解存儲(chǔ) Bean
獲取 Bean
添加 @Service 注解存儲(chǔ) Bean
獲取 Bean
添加 @Repository 注解存儲(chǔ) Bean
獲取 Bean
添加 @Component 注解存儲(chǔ) Bean
獲取 Bean
添加 @Configuration 注解存儲(chǔ) Bean
獲取 Bean
關(guān)于Id
通過(guò)添加注解的方式存儲(chǔ) Bean, 獲取 Bean 時(shí)的 Id 該如何命名??
- 當(dāng)類名為標(biāo)準(zhǔn)駝峰命名時(shí), 將類名的首字母小寫(xiě), 其余字母不變
- (例如類名為
UserInfo
, 其對(duì)應(yīng)的Id
為userInfo
)
- (例如類名為
- 當(dāng)類名的首字母為小寫(xiě)時(shí), 不做改變
- (例如類名為
userInfo
, 其對(duì)應(yīng)的Id
為userInfo
)
- (例如類名為
- 當(dāng)類名的首字母和第二個(gè)字母均為大寫(xiě), 不做改變
- (例如類名為
UInfo
, 其對(duì)應(yīng)的Id
為UInfo
)
- (例如類名為
源碼分析??
- AnnotationBeanNameGenerator
- Annotation, 注解
- BeanName, 對(duì)象名
- Generator, 生成
- Annotation BeanName Generator, 生成對(duì)象名注解
找到AnnotationBeanNameGenerator
的generateBeanName()
點(diǎn)擊buildDefaultBeanName()
點(diǎn)擊buildDefaultBeanName()
點(diǎn)擊decapitalize()
找到最終的調(diào)用方法
分析這段代碼
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))){ return name; }
如果長(zhǎng)度 > 1 且第 1 個(gè)字符與第 0 個(gè)字符均是大寫(xiě), 返回該字符串
(當(dāng)類名的首字母和第二個(gè)字母均為大寫(xiě), 不做改變)
chars[0] = Character.toLowerCase(chars[0]);
將第 0 個(gè)字符變?yōu)樾?xiě)
(當(dāng)類名為標(biāo)準(zhǔn)駝峰命名時(shí), 將類名的首字母小寫(xiě), 其余字母不變)
(當(dāng)類名的首字母為小寫(xiě)時(shí), 不做改變)
為什么需要五個(gè)類注解
既然都可以通過(guò)添加類注解的方式存儲(chǔ) Bean
那為何還需要五個(gè)類注解呢?
- 通過(guò)類注解可以了解當(dāng)前類的用途
- 具體的功能存在差異
舉個(gè)栗子??
通過(guò)車牌可以了解是哪里的車??, 例如 京 → 北京, 津 → 天津
(通過(guò)類注解可以了解當(dāng)前類的用途)
類注解的用途??
- @Controller(控制器), 歸屬于業(yè)務(wù)邏輯層, 用于校驗(yàn)用戶參數(shù)的有效性(控制用戶的行為)
- @Service(服務(wù)), 歸屬于服務(wù)層, 調(diào)用持久化類實(shí)現(xiàn)相應(yīng)的功能(不直接與數(shù)據(jù)庫(kù)交互, 類似于控制中心)
- @Repository(倉(cāng)庫(kù)), 歸屬于持久層, 直接與數(shù)據(jù)庫(kù)交互(通常一張表對(duì)應(yīng)一個(gè) @Repository)
- @Configuration(配置), 歸屬于配置層, 用于配置當(dāng)前項(xiàng)目的一些信息
- @Component(組件), 歸屬于公共工具類, 提供某些公共方法
舉個(gè)栗子??
滑稽老哥家中失竊, 選擇報(bào)警
接警員判斷情況是否屬實(shí), 避免小孩子的惡作劇
(@Controller)
警局根據(jù)接警員的信息派出一些警察負(fù)責(zé)跟進(jìn)
(@Service)
出警的警察負(fù)責(zé)這一起案件
(@Repository)
類注解之間的關(guān)系
@Component 是 @Controller, @Service, @Repository, @Configuration 的父類
利用方法注解進(jìn)行存儲(chǔ)
方法注解需搭配類注解一同使用
(目的是為了提高效率)
新建一個(gè) Student 類
新建一個(gè) StudentBeans 類
為 getStu() 添加方法注解(@Bean)
為 StudentBeans 添加類注解(@Component)
關(guān)于Id
- 默認(rèn)情況下 getBean() 對(duì)應(yīng)的 Id 為方法名
- @Bean 后可以跟 name
- (例如
@Bean(name = {"s1", "s2"})
)
- (例如
- 當(dāng) @Bean 后添加了 name 時(shí), 所對(duì)應(yīng)的 Id 只能為 name 名, 不允許設(shè)置為方法名
默認(rèn)情況下 getBean() 對(duì)應(yīng)的 Id 為方法名
@Bean 后可以跟 name
??Spring—獲取Bean
從 Spring 中獲取 Bean 也稱為對(duì)象裝配, 對(duì)象注入
對(duì)象裝配(對(duì)象注入)的方式可以劃分為 3 種
- 屬性注入
- Set 注入
- 構(gòu)造方法注入
屬性注入
屬性注入的效果等同于賦值
舉個(gè)栗子??
@Autowired
private StudentService studentService;
private int num = 10;
StudentService studentService
利用屬性注入, 由 Spring 框架賦值int num
未利用屬性注入, 由程序員賦值
綜上, 再次說(shuō)明了 Spring 是一個(gè)包含眾多工具方法的 IOC 容器
(IOC → 控制反轉(zhuǎn))
屬性注入的優(yōu)點(diǎn)??
- 實(shí)現(xiàn)簡(jiǎn)單
屬性注入的缺點(diǎn)??
- 不能注入不可變對(duì)象(final 修飾)
- 只適用于 IOC 容器
- 更容易違背單一設(shè)計(jì)原則
不能注入不可變對(duì)象(final 修飾)
final 修飾的對(duì)象有 2 種賦值方式
- 直接賦值
- 在構(gòu)造方法中賦值
只適用于 IOC 容器
@Autowired 來(lái)自于 Spring
Spring 是一個(gè)包含眾多工具方法的 IOC 容器
因此只適用于 IOC 容器
更容易違背單一設(shè)計(jì)原則
屬性注入的方式實(shí)現(xiàn)簡(jiǎn)單
因此也更容易將其他無(wú)關(guān)的對(duì)象一并注入
也就更容易違背單一設(shè)計(jì)原則
Set注入
Set 注入的優(yōu)點(diǎn)??
- 更符合單一設(shè)計(jì)原則
Set 注入的缺點(diǎn)??
- 不能注入不可變對(duì)象(final 修飾)
- 注入的對(duì)象可被修改
更符合單一設(shè)計(jì)原則
Set 注入的實(shí)現(xiàn)方式相比于屬性注入較復(fù)雜
因此相較于屬性注入也就避免了將其他無(wú)關(guān)的對(duì)象一并注入的情況
(更符合單一設(shè)計(jì)原則)
不能注入不可變對(duì)象(final 修飾)
final 修飾的對(duì)象有 2 種賦值方式
- 直接賦值
- 在構(gòu)造方法中賦值
注入的對(duì)象可被修改
Set 注入相較于屬性注入更危險(xiǎn)!
屬性注入的對(duì)象也可被修改
但 Set 注入除通過(guò)屬性注入的方式修改注入的對(duì)象
也可通過(guò) set() 方法修改注入的對(duì)象
set() 方法既可以被 Spring 調(diào)用
也可以被其他對(duì)象調(diào)用
構(gòu)造方法注入
注意
- 當(dāng)只存在一個(gè)構(gòu)造方法時(shí), @Autowired 可省略
- 當(dāng)存在多個(gè)構(gòu)造方法時(shí), @Autowired 不可省略
構(gòu)造方法注入的優(yōu)點(diǎn)??
- 能注入不可變對(duì)象(final 修飾)
- 注入的對(duì)象不可被修改
- final 修飾
- 構(gòu)造方法隨著類的加載只執(zhí)行一次
- 注入的對(duì)象會(huì)被完全初始化(類加載時(shí)就會(huì)將對(duì)象進(jìn)行初始化, 當(dāng)執(zhí)行其他方法時(shí), 對(duì)象已被初始化 → 構(gòu)造方法的機(jī)制)
- 通用性更好(任何一個(gè)類都會(huì)有構(gòu)造方法)
構(gòu)造方法注入的缺點(diǎn)??
- 實(shí)現(xiàn)方式不如屬性注入簡(jiǎn)單
總結(jié)(Spring的注入方式? 它們之間的區(qū)別?)
@Resource
- @Resource
- 可以實(shí)現(xiàn)屬性注入
- 可以實(shí)現(xiàn) Set 注入
- 不可以實(shí)現(xiàn)構(gòu)造方法注入
使用 @Resource 實(shí)現(xiàn)屬性注入
使用 @Resource 實(shí)現(xiàn) Set 注入
使用 @Resource 不能實(shí)現(xiàn)構(gòu)造方法注入
對(duì)比@Resource與@Autowired
來(lái)源不同??
@Resource
@Autowired
支持參數(shù)不同??
@Resource
@Autowired
Tips
存在返回同一個(gè)類型的多個(gè)方法時(shí)
利用@Resource(name = "")
可以將其進(jìn)行區(qū)分
@Autowired 無(wú)法設(shè)置 name
只能填寫(xiě)對(duì)應(yīng)的對(duì)象
如果想寫(xiě)成 student 形式
需搭配@Qualifier()
進(jìn)行使用, 括號(hào)中填寫(xiě)的內(nèi)容為對(duì)應(yīng)的對(duì)象
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-488396.html
??結(jié)尾
創(chuàng)作不易,如果對(duì)您有幫助,希望您能點(diǎn)個(gè)免費(fèi)的贊??
大家有什么不太理解的,可以私信或者評(píng)論區(qū)留言,一起加油文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-488396.html
到了這里,關(guān)于Spring的存儲(chǔ)與獲取Bean的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!