java構(gòu)造器復(fù)用方式
構(gòu)造器復(fù)用
創(chuàng)建一個(gè)Employee類,屬性有(名字,性別,年齡,職位,薪水),提供3個(gè)構(gòu)造方法,可以初始化(⑴)(名字,性別,年齡,職位,薪水),(2)(名字,性別,年齡)(3)(職位,薪水).要求充分復(fù)用構(gòu)造器Hello.java
public class Hello { public static void main(String[] args) { } } class EMployee{ String name; char gender; int age; String job; double sal; // 職位 薪水 public EMployee(String job,double sal) { this.job = job; this.sal = sal; } // 姓名 性別 年齡 public EMployee(String name,char gender,int age) { this.name = name; this.gender = gender; this.age = age; } // 名字 性別 年齡 職位 薪水 public EMployee(String job,double sal,String name,char gender,int age) { this(name,gender,age); this.job = job; this.sal = sal; } }
推薦使用構(gòu)造器注入
? Spring框架對(duì)Java開(kāi)發(fā)的重要性不言而喻,平時(shí)使用最多的就是其中的IOC,我們通過(guò)將組件交由Spring的IOC容器管理,將對(duì)象的依賴關(guān)系由Spring控制,避免硬編碼所造成的過(guò)度程序耦合。
前幾天的時(shí)候,朋友問(wèn)我為什么要使用構(gòu)造器的注入方式,后面抽時(shí)間了解了一下,下面就是筆者要討論的就是其注入方式。
常見(jiàn)的三種注入方式
field注入
@Controller public class FooController { @Autowired //@Inject private FooService fooService; //簡(jiǎn)單的使用例子,下同 public List<Foo> listFoo() { return fooService.list(); } }
這種注入方式應(yīng)該是筆者目前為止開(kāi)發(fā)中見(jiàn)到的最常見(jiàn)的注入方式。原因很簡(jiǎn)單:
- 注入方式非常簡(jiǎn)單:加入要注入的字段,附上
@Autowired
,即可完成。 - 使得整體代碼簡(jiǎn)潔明了,看起來(lái)美觀大方。
構(gòu)造器注入
@Controller public class FooController { private final FooService fooService; @Autowired public FooController(FooService fooService) { this.fooService = fooService; } //使用方式上同,略 }
setter注入
@Controller public class FooController { private FooService fooService; //使用方式上同,略 @Autowired public void setFooService(FooService fooService) { this.fooService = fooService; } }
構(gòu)造器注入的好處
- 依賴不可變:其實(shí)說(shuō)的就是final關(guān)鍵字,這里不再多解釋了。不明白的園友可以回去看看Java語(yǔ)法。
- 依賴不為空(省去了我們對(duì)其檢查):當(dāng)要實(shí)例化FooController的時(shí)候,由于自己實(shí)現(xiàn)了有參數(shù)的構(gòu)造函數(shù),所以不會(huì)調(diào)用默認(rèn)構(gòu)造函數(shù),那么就需要Spring容器傳入所需要的參數(shù),所以就兩種情況:1、有該類型的參數(shù)->傳入,OK 。2:無(wú)該類型的參數(shù)->報(bào)錯(cuò)。所以保證不會(huì)為空,Spring總不至于傳一個(gè)null進(jìn)去吧 ??
- 完全初始化的狀態(tài):這個(gè)可以跟上面的依賴不為空結(jié)合起來(lái),向構(gòu)造器傳參之前,要確保注入的內(nèi)容不為空,那么肯定要調(diào)用依賴組件的構(gòu)造方法完成實(shí)例化。而在Java類加載實(shí)例化的過(guò)程中,構(gòu)造方法是最后一步(之前如果有父類先初始化父類,然后自己的成員變量,最后才是構(gòu)造方法,這里不詳細(xì)展開(kāi)。)。所以返回來(lái)的都是初始化之后的狀態(tài)。
//承接上面field注入的代碼,假如客戶端代碼使用下面的調(diào)用(或者再Junit測(cè)試中使用) //這里只是模擬一下,正常來(lái)說(shuō)我們只會(huì)暴露接口給客戶端,不會(huì)暴露實(shí)現(xiàn)。 FooController fooController = new FooController(); fooController.listFoo(); // -> NullPointerException
如果使用field注入,缺點(diǎn)顯而易見(jiàn),對(duì)于IOC容器以外的環(huán)境,除了使用反射來(lái)提供它需要的依賴之外,無(wú)法復(fù)用該實(shí)現(xiàn)類。而且將一直是個(gè)潛在的隱患,因?yàn)槟悴徽{(diào)用將一直無(wú)法發(fā)現(xiàn)NPE的存在。
還值得一提另外一點(diǎn)是:使用field注入可能會(huì)導(dǎo)致循環(huán)依賴,即A里面注入B,B里面又注入A:
public class A { @Autowired private B b; } public class B { @Autowired private A a; }
如果使用構(gòu)造器注入,在spring項(xiàng)目啟動(dòng)的時(shí)候,就會(huì)拋出:
BeanCurrentlyInCreationException:Requested bean is currently in creation: Is there an unresolvable circular reference?
從而提醒你避免循環(huán)依賴,如果是field注入的話,啟動(dòng)的時(shí)候不會(huì)報(bào)錯(cuò),在使用那個(gè)bean的時(shí)候才會(huì)報(bào)錯(cuò)。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中的動(dòng)態(tài)數(shù)組和棧Vector Stack使用區(qū)別介紹
這篇文章主要為大家介紹了Java中的動(dòng)態(tài)數(shù)組和棧Vector Stack使用介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10Spring Boot使用Druid進(jìn)行維度的統(tǒng)計(jì)和監(jiān)控
這篇文章主要介紹了Spring Boot使用Druid進(jìn)行維度的統(tǒng)計(jì)和監(jiān)控,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-04-04關(guān)于mybatis-plus邏輯刪除無(wú)效的問(wèn)題
這篇文章主要介紹了mybatis-plus邏輯刪除無(wú)效,文中給大家提到了配置過(guò)程及全部代碼,代碼簡(jiǎn)單易懂,需要的朋友可以參考下2021-09-09Java使用ExecutorService來(lái)停止線程服務(wù)
這篇文章主要介紹了Java使用ExecutorService來(lái)停止線程服務(wù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04在IntelliJ IDEA中創(chuàng)建和運(yùn)行java/scala/spark程序的方法
這篇文章主要介紹了在IntelliJ IDEA中創(chuàng)建和運(yùn)行java/scala/spark程序的教程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05SpringBoot整合MyBatis逆向工程及 MyBatis通用Mapper實(shí)例詳解
這篇文章主要介紹了SpringBoot整合MyBatis逆向工程及 MyBatis通用Mapper實(shí)例詳解 ,需要的朋友可以參考下2017-09-09詳解Spring boot Admin 使用eureka監(jiān)控服務(wù)
本篇文章主要介紹了詳解Spring boot Admin 使用eureka監(jiān)控服務(wù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12