目錄
1、什么是Spring:
2.什么是IoC:
3. 什么是控制反轉呢??
4.IoC容器具備以下優點:
5.DI是什么:
依賴注?方法:
三種注入方法的優缺點:
@Autowired注解注入存在的問題:
@Autowired和@Resource的區別:
6.IoC和DI的使用:
7.Bean的存儲:
8.Bean的命名:
9.ApplicationContext VS BeanFactory
10.Bean的掃描路徑:
10.Spring, Spring Boot 和Spring MVC的關系以及區別:
11.
12.Spring框架中的Bean是否是線程安全的:
1、什么是Spring:
Spring是一個開源框架,他讓我們的開發更加簡單. 他?持?泛的應?場景, 有著活躍?龐?的社區
,是包含了眾多工具方法的IoC容器。
2.什么是IoC:
IoC: Inversion of Control (控制反轉), 也就是說 Spring 是?個"控制反轉"的容器.
IoC 是Spring的核?思想,在類上?添加 @RestController 和 @Controller 注解, 就是把這個對象交給Spring管理, Spring 框架啟動時就會加載該類. 把對象交給Spring管理, 就是IoC思想.
3. 什么是控制反轉呢??
獲得依賴對象的過程被反轉了。也就是說, 當需要某個對象時, 傳統開發模式中需要??通過 new 創建對象, 現在不需要再進?創建, 把創建對象的任務交給容器, 程序中只需要依賴注? (Dependency Injection,DI)就可以了.
這個容器稱為:IoC容器. Spring是?個IoC容器, 所以有時Spring 也稱為Spring 容器.
4.IoC容器具備以下優點:
資源不由使?資源的雙?管理,?由不使?資源的第三?管理,這可以帶來很多好處。
第?,資源集中管理,實現資源的可配置和易管理。IoC容器會幫我們管理?些資源(對象等), 我們需要使?時, 只需要從IoC容器中去取就可以了
第?,降低了使?資源雙?的依賴程度,也就是我們說的耦合度。我們在創建實例的時候不需要了解其中的細節。
Spring 就是?種IoC容器, 幫助我們來做了這些資源管理.
5.DI是什么:
DI: Dependency Injection(依賴注?)
容器在運?期間, 動態的為應?程序提供運?時所依賴的資源,稱之為依賴注?。程序運?時需要某個資源,此時容器就為其提供這個資源。簡單來說, 就是把對象取出來放到某個類的屬性中.
從這點來看, 依賴注?(DI)和控制反轉(IoC)是從不同的?度的描述的同?件事情,就是指通過引? IoC 容器,利?依賴關系注?的?式,實現對象之間的解耦。可以說, DI 是IoC的?種實現.
依賴注?方法:
?Spring也給我們提供了三種?式:
1. 屬性注?(Field Injection):使用@Autowired實現
2. 構造?法注?(Constructor Injection):在類的構造?法中實現注?,搭配@Autowired注解
注意事項:如果類只有?個構造?法,那么 @Autowired 注解可以省略;如果類中有多個構造?法,那么需要添加上 @Autowired 來明確指定到底使?哪個構造?法
3. Setter 注?(Setter Injection):和屬性的 Setter ?法實現類似,只不過在設置 set ?法的時候需要加上 @Autowired 注解 。
三種注入方法的優缺點:
屬性注入:
優點:代碼簡介,使用簡單。
?缺點:只能作用于 IoC容器,不能注入final修飾的類。
構造方法注入:
優點:可以注?final修飾的屬性 ;?注?的對象不會被修改;依賴對象在使?前?定會被完全初始化,因為依賴是在類的構造?法中執?的,?構造?法是在類加載階段就會執?的?法;通?性好, 構造?法是JDK?持的, 所以更換任何框架,他都是適?的。
?缺點:??注?多個對象時, 代碼會?較繁瑣
? Setter注?
優點: ?便在類實例之后, 重新對該對象進?配置或者注?
?缺點: 不能注??個Final修飾的屬性;注?對象可能會被改變, 因為setter?法可能會被多次調?, 就有被修改的?險
@Autowired注解注入存在的問題:
當同?類型存在多個bean時,僅通過類 類型注入時,會找到非唯一的Bean對象。
可以通過一下方法解決:
1. @Primary注解:當存在多個相同類型的Bean注?時,加上@Primary注解,來確定默認的實現.
2. @Qualifier注解:通過該注解的value屬性,指定當前要注入的Bean的名稱;不能單獨使用,要搭配@Autowired注解使用。
3.@Resource注解:按照Bean的名稱注入,通過name屬性指定要注入的Bean的名稱。
@Autowired和@Resource的區別:
相同點:
1. @Resource和@Autowired都是做bean的注入時使用。
2.兩者都可以寫在字段和setter方法上;不同點:
1.@Autowired是Spring框架提供的注解;@Resource并不是Spring的注解,是JDK提供的注解,它的包是javax.annotation.Resource,需要導入;
2.@Autowired是按照類型注入的,默認情況下它要求依賴對象必須存在,如果允許null值,可以設置它的required屬性為false。如果我們想使用按照名稱(byName)來裝配,可以結合@Qualifier注解一起使用;
@Resource是按照名稱注入的,@Resource有兩個重要的屬性: name和type,而Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以,如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不制定name也不制定type屬性,這時將通過反射機制使用byName自動注入策略。
@Resource裝配順序:
①如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常。
②如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常。
③如果指定了type,則從上下文中找到類似匹配的唯一bean進行裝配,找不到或是找到多個,都會拋出異常。
④如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始類型進行匹配,如果匹配則自動裝配。
6.IoC和DI的使用:
Spring 容器 管理的主要是對象, 這些對象, 我們稱之為"Bean". 我們把這些對象交由Spring管理, 由Spring來負責對象的創建和銷毀(實現作為容器的存和取的功能).
7.Bean的存儲:
要把某個對象交給IOC容器管理,需要在類上添加?個注解: @Component ,?Spring框架為了更好的服務web應?程序, 提供了更豐富的注解:
1. 類注解:@Controller(控制器存儲):控制層, 接收請求, 對請求進?處理, 并進?響應
@Service(服務存儲):業務邏輯層, 處理具體的業務邏輯
@Repository(倉庫存儲):數據訪問層,也稱為持久層. 負責數據訪問操作
@Configuration(配置存儲):配置層. 處理項?中的?些配置信息
@Component(組件存儲):該注解是一個元注解,這幾個注解是該注解的衍生類。
2. ?法注解:@Bean.
分配這么多注解的作用:和應?分層是呼應的. 讓程序員看到類注解之后,就能直接了解當前類的?途。
方法注解的使用場景:
1. 使?外部包?的類, 沒辦法添加類注解
2. ?個類, 需要多個對象, ?如多個數據源 。這種場景, 我們就需要使??法注解 @Bean
(方法注解要配合類注解使用)
8.Bean的命名:
程序開發?員不需要為bean指定名稱(BeanId), 如果沒有顯式的提供名稱(BeanId),Spring容器將為該bean?成唯?的名稱。命名約定使?Java標準約定作為實例字段名. 也就是說,bean名稱以?寫字?開頭,然后使?駝峰式??寫.
?如:
類名: UserController, Bean的名稱為: userController
類名: AccountManager, Bean的名稱為: accountManager
當有多個字符并且第?個和第?個字符都是?寫時, 將保留原始的??寫。
?如
類名: UController, Bean的名稱為: UController
類名: AManager, Bean的名稱為: AManager
9.ApplicationContext VS BeanFactory
獲取bean對象, 是ApplicationContext的?類BeanFactory提供的功能。
? 繼承關系和功能??來說:
Spring 容器有兩個頂級的接?:BeanFactory 和ApplicationContext。其中 BeanFactory 提供了基礎的訪問容器的能?,?ApplicationContext 屬于 BeanFactory 的?類,還實現了多個別的接口,它除了繼承了 BeanFactory 的所有功能之外,它還擁有獨特的特性,還添加了對國際化?持、資源訪問?持、以及事件傳播等??的?持.
? 從性能??來說:延遲加載
1. BeanFactroy 采用的是延遲加載形式來注入 Bean 的,即只有在使用到某個 Bean 時(調用getBean()),才對該 Bean 進行加載實例化。這樣,我們就不能發現一些存在的 spring 的配置問題。而 ApplicationContext 則相反,它是在容器啟動時,一次性創建了所有的 Bean。這樣,在容器啟動時,我們就可以發現 Spring 中存在的配置錯誤
10.Bean的掃描路徑:
使?五?注解聲明的bean,要想?效, 還需要配置掃描路徑, 讓Spring掃描到這些注解 也就是通過 @ComponentScan 來配置掃描路徑。
在之前的使用中@ComponentScan 注解雖然沒有顯式配置,但也訪問成功了,是因為該注解已經包含在了啟動類聲明注解@SpringBootApplication 中了,默認掃描的范圍是SpringBoot啟動類所在包及其?包,在配置類上添加 @ComponentScan 注解, 該注解默認會掃描該類所在的包下所有的配置類。
10.Spring, Spring Boot 和Spring MVC的關系以及區別:
Spring:Spring 是?個開發應?框架,特點是:輕量級、?站式、模塊化,其?的是?于簡化企業級應?程序開發.
Spring的主要功能: 管理對象,以及對象之間的依賴關系, ?向切?編程, 數據庫事務管理, 數據訪問, web框架?持等。但是Spring具備?度可開放性, 并不強制依賴Spring。
Spring MVC: Spring MVC是Spring的?個?框架, 按照MVC模式設計了?個 MVC框架(?些?Spring 解耦的組件), 主要?于開發WEB應?和?絡接?,Spring MVC 是?個Web框架。
Spring Boot: Spring Boot是對Spring的?個封裝, 為了簡化Spring應?的開發?出現的,使?Spring Boot 可以更加快速的搭建框架, 降級開發成本, 讓開發?員更加專注于Spring應?的開發,??需過多關注XML的配置和?些底層的實現。
pring MVC和Spring Boot都屬于Spring,Spring MVC 是基于Spring的?個 MVC 框架,?Spring Boot 是基于Spring的?套快速開發整合包.
11.
12.Spring框架中的Bean是否是線程安全的:
Spring 框架并沒有對單例 Bean 進行任何多線程的封裝處理。
關于單例 Bean 的線程安全和并發問題,需要開發者自行去搞定。單例的線程安全問題,并不是 Spring 應該去關心的。 Spring 應該做的是,提供根據配置,創建單例 Bean 或多例 Bean 的功能。但實際上,大部分的 Spring Bean 并沒有可變的狀態,所以在某種程度上說 Spring 的單例Bean 是線程安全的。如果你的 Bean 有多種狀態的話,就需要自行保證線程安全。最淺顯的解決辦法,就是將多態 Bean 的作用域(Scope)由 Singleton 變更為 Prototype。
13.Spring如何解決循環依賴問題:
循環依賴:循環引用,就是兩個或兩個以上的bean對象互相持有對方,最終形成了閉環,如:A引用B,B引用C,C又引用A,就形成了循環引用。
處理整個流程大致如下:
1. 首先 A 完成初始化第一步并將自己提前曝光出來(通過 ObjectFactory 將自己提前曝光),在初始化的時候,發現自己依賴對象 B,此時就會去嘗試 get(B),這個時候發現 B 還沒有被創建出來;
2. 然后 B 就走創建流程,在 B 初始化的時候,同樣發現自己依賴 C,C 也沒有被創建出來;
3. 這個時候 C 又開始初始化進程,但是在初始化的過程中發現自己依賴 A,于是嘗試 get(A)。這
個時候由于 A 已經添加至緩存中(一般都是添加至三級緩存 singletonFactories),通過ObjectFactory 提前曝光,所以可以通過 ObjectFactory#getObject() 方法來拿到 A 對象。 C 拿到 A 對象后順利完成初始化,然后將自己添加到一級緩存中;
4. 回到 B, B 也可以拿到 C 對象,完成初始化, A 可以順利拿到 B 完成初始化。到這里整個鏈路
就已經完成了初始化過程了。