[問題]沒有autowired會要自己new一堆很深的建構?

看板java作者 (阿龍)時間1年前 (2022/05/09 01:04), 1年前編輯推噓0(0040)
留言40則, 3人參與, 1年前最新討論串1/3 (看更多)
之前問過類似的問題 大概知道了autowired的好處 比如說 Spring @Autowired 搭配 @Qualifier 指定注入的Bean 重點在 依賴於介面 而不依賴於實作 這樣抽換的時候就會方便很多 但是還是有一個地方不太懂 就是說如果有層層的依賴關係的話 沒有autowired就會出現 一層層的new 建構子出現 但是我自己舉了幾個例子 並沒有出現一層層 new的建構子 之前軟體版有人回答過我,但是那連結已經失效了QQ 假設Service1 依賴於 Dao1 ,Dao1又依賴於Dao11和Dao22好了 以下是我的測試CODE 1. Dao11 public class Dao11 { public void sayhi() { System.out.println("hi"); } } 2.Dao22 public class Dao22 { public void sayhi2() { System.out.println("hi fomr dao22"); } } 3. Dao1 public class Dao1 { // private Dao11 dao11; Dao11 dao11=new Dao11(); Dao22 dao22=new Dao22(); public void sayhifromDao1() { dao11.sayhi(); dao22.sayhi2(); } } 4. Service1 public class Service1 { Dao1 dao1=new Dao1( ); public void sasdf() { dao1.sayhifromDao1(); } } 5. Main Class public class MainDriver { public static void main(String[] args) { Service1 service=new Service1(); service.sasdf(); } } 我的疑惑是不管我的Service依賴了幾層東西 最後都是非常乾淨清爽的 一行 new Service1 (); 並且是空的建構子,就可以做到 那這樣就我的理解,是不是只要我沒有宣告 field在class裡面 意思就是我沒有宣告 // private Dao11 dao11; 在Dao1 裡面 不管我的Service1 依賴多少東西 ,最後都可以用空的建構子new出來 並且保證功能正常運行 第二個問題是 怎麼樣造出那些 真的會有需要 層層 new的例子 這方面想不太出來 謝謝JAVA版 這幾天又一直瘋狂糾結這件事.... -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.225.243.102 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/java/M.1652029491.A.B56.html

05/09 04:46, 1年前 , 1F
你只用你自己寫的程式當然覺得都用無參數建構子就好
05/09 04:46, 1F

05/09 04:47, 1年前 , 2F
假設你的Dao需要個一定得從外面傳進來的DataSource
05/09 04:47, 2F

05/09 04:48, 1年前 , 3F
勢必要改成這一串相依類別的建構子都要有DataSource參數
05/09 04:48, 3F

05/09 04:49, 1年前 , 4F
「所有類別都能用無參數建構子new出來」是你一廂情願的想法
05/09 04:49, 4F

05/09 04:52, 1年前 , 5F
就算不用依賴注入,把Dao的new直接寫在Service的裡也不是好
05/09 04:52, 5F

05/09 04:52, 1年前 , 6F
事,這代表Dao的建構子一改你所有new到他的Service都要改
05/09 04:52, 6F

05/09 04:55, 1年前 , 7F
這就是直接依賴實作的問題,即使沒有特別抽出interface,只
05/09 04:55, 7F

05/09 04:56, 1年前 , 8F
呼叫public method是只依賴於介面,呼叫到建構子是綁死實作
05/09 04:56, 8F

05/09 08:38, 1年前 , 9F
晚點來看一下Data source例子,謝謝
05/09 08:38, 9F
https://i.imgur.com/5Is3GmX.jpg
https://i.imgur.com/IJHRcWy.jpg
不知道你說的是不是這種例子 但看起來用getDatasouce好像也沒有依賴實作的問題 可能我找的例子沒很好 抱歉 ※ 編輯: ntpuisbest (36.225.243.102 臺灣), 05/09/2022 20:31:34

05/09 21:17, 1年前 , 10F
你在你的Dao裡面是要怎麼呼叫getDatasource?
05/09 21:17, 10F
我看他的測試程式碼,並沒有呼叫getDatasource這個方法,但有autowired他 是代表autowired自動會為了注入,所以呼叫getter嗎? 然後@Bean註解也有發揮效用? ※ 編輯: ntpuisbest (49.216.234.222 臺灣), 05/09/2022 22:24:47 https://www.796t.com/content/1549926748.html 我覺得可能跟這有關,不確定他怎麼做掉的 https://i.imgur.com/futmx4a.jpg
https://i.imgur.com/FD36yv2.jpg
※ 編輯: ntpuisbest (49.216.234.222 臺灣), 05/09/2022 23:22:24

05/10 00:22, 1年前 , 11F
那個getDatasource不是getter,是定義一個Bean (由spring的
05/10 00:22, 11F

05/10 00:23, 1年前 , 12F
ApplicationContext管理的物件),spring的@Autowired或其他
05/10 00:23, 12F

05/10 00:26, 1年前 , 13F
注入方式並不是找任意類別,只會從ApplicationContext中註
05/10 00:26, 13F

05/10 00:27, 1年前 , 14F
冊的Bean裡找名稱/類別/Qualifer符合的
05/10 00:27, 14F

05/10 00:28, 1年前 , 15F
先不談spring怎麼做的,先集中在你一開始的問題,所以你把
05/10 00:28, 15F

05/10 00:29, 1年前 , 16F
你的Service、Dao1、Dao11寫好了,現在Dao11裡面要這個
05/10 00:29, 16F

05/10 00:31, 1年前 , 17F
DataSource,你main裡只有Service1 service=new Service1()
05/10 00:31, 17F

05/10 00:31, 1年前 , 18F
你要怎麼改?
05/10 00:31, 18F
那這樣就無法是空的建構子了? 但我陷入的僵局是jdbc的連線資訊寫死在 application.properties裡面 如果是一般的物件,比如說是Company裡面有一個member是員工好了 我還可以理解new Employee("name",age) new Company(new Employee("name",age) 但是對於寫死的,要更改只要更改 applicstion.properties就好 我寫的有點亂 我知道要跟資料庫連線一定要有連線資訊 所以我一定要將連線資訊注入dao 那如果說autowired在datasource上幫我注入了好了 那沒有autowired這個註解,我要怎麼注入? 就我以前學的理解最早應該都是封裝一個類別來get connection 差不多這樣 Connection conn = DBUtils.getConn(); 那如果是這樣我好像也不會看到一層層的new (高耦合) 還有依賴於dao的service如果沒有autowired註解的話 是不是就會有一層層new了呢?

05/10 00:34, 1年前 , 19F
是說你問法很像只有在找範例讀、寫些只有sout的測試,建議
05/10 00:34, 19F

05/10 00:35, 1年前 , 20F
先找個題目寫個會動的系統,真正用過這些功能再問
05/10 00:35, 20F

05/10 00:42, 1年前 , 21F
工具是解決問題用的,你沒有問題要解決,拿著工具再怎麼問
05/10 00:42, 21F

05/10 00:43, 1年前 , 22F
它哪裡好用,得到答案你的感覺還是這有什麼用?
05/10 00:43, 22F

05/10 00:45, 1年前 , 23F
對你現在都在一個main就做完的需求,的確這些工具都沒用
05/10 00:45, 23F
因為我上班一年下來 幾乎都是在application.properties裡面就把database的連線設定寫好,因為我們不會同 時連超過兩個資料庫,雖然還是有分dev跟prod 不過就只是用spring.profiles.active=xxxx而已 平常工作就是寫restful api,複雜一點頂多表格多一點join 只是我這次面試下來發現很多面試官都超愛問我 spring ioc能幹嘛幹嘛 結果當我反問我在版上舉的那些例子的時候 每個人都跟我說降低了耦合 我就會問那我這樣new一個空的建構子到底跟 autowired差在哪? 幾乎每個都垮(當然我面試的工作最高薪頂多70萬而已) 但我還是覺得很扯 只有一個提到搭配介面還有qualifierd註解 各式各樣的文章都強調 ioc跟di是spring的核心價值 但或許是因為我一直在用spring boot 平常也是無腦autowired dao 到service service到controller這樣 總之我覺得這應該是很基本的東西 但我工作快一年掌握度還很低 讓我覺得不該是這樣

05/10 00:48, 1年前 , 24F
程式內容農場少看比較好…
05/10 00:48, 24F

05/10 00:49, 1年前 , 25F
連等寬字型都沒有的code沒有看的價值
05/10 00:49, 25F
※ 編輯: ntpuisbest (49.216.234.222 臺灣), 05/10/2022 02:11:49 好像大概懂了 我在field裡面新增了word https://imgur.com/a/dKHqjIw 這樣大概看出autowired的好處了 ※ 編輯: ntpuisbest (49.216.234.222 臺灣), 05/10/2022 19:59:32

05/12 02:42, 1年前 , 26F
雖然你好像終於看出@Autowired的用處了,但是其實這只是
05/12 02:42, 26F

05/12 02:44, 1年前 , 27F
@Autowired能直接用在field得到的方便,不是IoC/DI的好處
05/12 02:44, 27F

05/12 02:51, 1年前 , 28F
以你上面的code來說,其實硬要繼續用無參數ctor也不是不行
05/12 02:51, 28F

05/12 02:53, 1年前 , 29F
開setter也行,甚至也可以手動reflection取代@Autowired
05/12 02:53, 29F

05/12 02:54, 1年前 , 30F
spring DI的重點是根本不用自己寫那段「組裝」的程式碼,只
05/12 02:54, 30F

05/12 02:55, 1年前 , 31F
要依照spring的慣例定義好相依關係,啟動context就會自動組
05/12 02:55, 31F

05/12 02:57, 1年前 , 32F
好,組裝方式可以用field/setter/ctor都支援,@Autowired不
05/12 02:57, 32F

05/12 02:59, 1年前 , 33F
過是標示而已,有參數的ctor也不是問題
05/12 02:59, 33F

05/12 03:00, 1年前 , 34F
(題外話,如果只有一個ctor,不需要@Autowired標示spring也
05/12 03:00, 34F
這個我知道喔,只有一個的話不用標

05/12 03:12, 1年前 , 35F
認得,我個人習慣盡可能用這種方式,可以做到immutable,也
05/12 03:12, 35F

05/12 03:22, 1年前 , 36F
保證需要自己new的時候不會漏掉依賴,當pojo用也行)
05/12 03:22, 36F

05/12 03:28, 1年前 , 37F
然後你說工作上沒碰過複雜的組裝,要不真的是micro service
05/12 03:28, 37F

05/12 03:30, 1年前 , 38F
化/AOP用的很成功那沒話說,要不就是Service其實太肥了
05/12 03:30, 38F

05/12 03:39, 1年前 , 39F
不是單純CRUD的系統,Service常常會需要多個Service或其他
05/12 03:39, 39F

05/12 03:51, 1年前 , 40F
handler、adapter...之類@Component組成的吧
05/12 03:51, 40F
我的service通常裡面也會需要用到其他很多crud service 其實我沒寫過apapter handler 但我有用spring security寫過一個custom login page的系統連過mysql 就我這裡的理解由於service裡面都有用到dao 所以其實autowired註解真正用在dao的效用還比較大? 因為要注入連線資訊到dao裡面 但在controller中應該是可以無參數子的new service()吧,手頭沒電腦不太確定 ※ 編輯: ntpuisbest (49.216.80.89 臺灣), 05/13/2022 00:25:37
文章代碼(AID): #1YT_WpjM (java)
文章代碼(AID): #1YT_WpjM (java)