深入理解Spring(IOC)(一)

what is IOC?
控制反轉(Inversion of Control,縮寫爲IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)
DI:只是實現IOC的其中一種方式(除了DI 還有依賴查找)
依賴查找:如“javaJNDI”
依賴注入:Dependency Injection
關於什麼是依賴?(當一個類中擁有了一個屬性,就可以說當前類依賴這個屬性)
關於注入和查找以及拖拽

爲什麼要使用spring IOC(官網
在日常程序開發過程當中,我們推薦面向抽象編程,面向抽象編程會產生類的依賴,當然如果你夠強大可以自己寫一個管理的容器,但是既然spring以及實現了,並且spring如此優秀,我們僅僅需要學習spring框架便可。
當我們有了一個管理對象的容器之後,類的產生過程也交給了容器,至於我們自己的app則可以不需要去關係這些對象的產生了。
spring實現IOC的思路和方法
spring實現IOC的思路是提供一些配置信息用來描述類之間的依賴關係,然後由容器去解析這些配置信息,繼而維護好對象之間的依賴關係,前提是對象之間的依賴關係必須在類中定義好,比如A.class中有一個B.class的屬性,那麼我們可以理解爲A依賴了B。既然我們在類中已經定義了他們之間的依賴關係那麼爲什麼還需要在配置文件中去描述和定義呢?
spring實現IOC的思路大致可以拆分成3點
1、應用程序中提供類,提供依賴關係(屬性或者構造方法)
2、把需要交給容器管理的對象通過配置信息告訴容器(xml、annotation,javaconfig)
3、把各個類之間的依賴關係通過配置信息告訴容器

配置這些信息的方法有三種分別是xml,annotation(如@compent)和javaconfig(如@Bean
維護的過程稱爲自動注入,自動注入的方法有兩種構造方法和setter
自動注入的值可以是對象,數組,map,list和常量比如字符串整形等

如下圖 a 依賴 b 通過XML 配置方式告訴容器 ,那爲什麼還需要在XML中配置呢?a已經在代碼中依賴了b,這一步是否多餘了?我們先思考一下?
解答見下面 自動裝配
在這裏插入圖片描述
spring編程的風格
1、schemal-based-------xml
2、annotation-based-----annotation
3、java-based----java Configuration(springBoot基於java Configuration
注入的兩種方法(spring3 時還提供接口注入方式由於太不人性化spring4取消了)
1.spring注入詳細配置(字符串、數組等)參考文檔:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html
Constructor-based Dependency Injection(構造方式)
構造方法注入參考文檔:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html
在這裏插入圖片描述
Setter-based Dependency Injection(set方法方式)
setter參考文檔:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html
在這裏插入圖片描述
自動裝配
上面說過,IOC的注入有兩個地方需要提供依賴關係,一是類的定義中,二是在spring的配置中需要去描述。自動裝配則把第二個取消了,即我們僅僅需要在類中提供依賴,繼而把對象交給容器管理即可完成注入。
在實際開發中,描述類之間的依賴關係通常是大篇幅的,如果使用自動裝配則省去了很多配置,並且如果對象的依賴發生更新我們可以不需要去更新配置,但是也帶來了一定的缺點
自動裝配的優點參考文檔:(1、省去繁瑣的property屬性配置 2、自動匹配代碼中的依賴變化
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-autowire
缺點參考文檔:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-autowired-exceptions
作爲個人來講,我覺得以上缺點都不是缺點

自動裝配的方法
no(不使用自動裝配
byName(**XML方式byName是根據類中的set方法名進行裝配 如:setDao 則裝配名稱爲dao的對象,但是如果用@Resource註解默認也是byName裝配則使用的是屬性的名字裝配 **)
byType(byType是根據類型進行裝配,spring會初始化所有對象然後去遍歷,查找需要裝配的父類類型。若接口有多實現時會報錯 @Autowired註解也是根據byType方式裝配,如果沒找到則採用byType
解決辦法:XML可以全局指定裝配方式,還可以爲每個對象單獨指定裝配
在這裏插入圖片描述
constructor
自動裝配的方式參考文檔:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-autowire
在這裏插入圖片描述
上面說到 @Autowired與 @Resource 這裏提一下他們兩個註解的區別:
@Autowired
1、是由spring代碼中定義
2、默認採取byType方式完成裝配
3、如果沒有找到則採用byType方式裝配
4、默認情況下它要求依賴對象必須存在找不到就拋異常,如果允許null值,可以設置它required屬性爲false。如果我們想使用按名稱裝配,可以結合@Qualifier註解一起使用

@Resource
1、是java Jdk即J2EE提供
2、默認按byName自動注入,也提供按照byType 注入
3. 如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常
4. 如果指定了type,則從上下文中找到類型匹配的唯一bean進行裝配,找不到或者找到多個,都會拋出異常
5. 如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退爲一個原始類型進行匹配,如果匹配則自動裝配,如果不匹配則會拋出異常;

使用方法XML方式
在這裏插入圖片描述
使用方式註解方式
在這裏插入圖片描述
spring懶加載
官網已經解釋的非常清楚了(get的時候纔會創建Bean):
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-lazy-init
值得提醒的是,如果你想爲所有的對都實現懶加載可以使用官網的配置
在這裏插入圖片描述
springbean的作用域
文檔參考:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-scopes
在這裏插入圖片描述
xml定義方式



<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

annotation的定義方式(定義這個類是單例還是多例)
在這裏插入圖片描述
Singleton Beans with Prototype-bean Dependencies(當單例的對象,引用多例的對象時Prototype會失去意義)
意思是在Singleton 當中引用了一個Prototype的bean的時候引發的問題
官網引導我們參考https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-method-injection
在這裏插入圖片描述
(非常重要)問題產生原因描述:
問題描述 如下圖:聲明idexDao對象爲多例模式,indexService爲默認單例模式。然後調用三次Dao.hashcode
則發現他的hashCode爲一莫一樣。如圖:那麼單例對象引用多例對象時@Scope(“prototype”)就失去了意義。
在這裏插入圖片描述
在這裏插入圖片描述
原因分析: 由於spring初始化indexService時。只會初始化一次,那麼它只有一次設置indexDao的機會,所以indexDao變成了單例
解決方式(一): 缺點:代碼侵入性太高。必須實現spring的一個接口ApplicationContextAware
在這裏插入圖片描述
解決方式(二) @Lookup註解方式
在這裏插入圖片描述
spring聲明週期和回調(見下一篇
參考文檔:
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-lifecycle

1、Methods annotated with @PostConstruct
2、afterPropertiesSet() as defined by the InitializingBean callback interface
3、A custom configured init() method

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章