摘要:構造器自動裝配方法自動裝配其他方法自動裝配不管是構造器,方法還是其他的方法,都會去嘗試滿足方法參數上所聲明的依賴。所以上面的輸出是構造器自動裝配方法自動裝配其他方法自動裝配使用進行自動裝配的時候,需要注意一下幾點。
完整代碼請見:https://github.com/codercuixi...
創建應用對象之間協作關系的行為通常稱為裝配(wiring),這也是依賴注入(DI)的本質。
在xml文件中顯式配置(基本上公司中都不用了)
在Java中進行顯式配置
隱式的bean發現機制和自動裝配
建議:盡可能使用自動配置的機制,顯式配置越少越好。
當你必須要顯式配置bean的時候(比如源碼不是由你來維護的,而你需要這些代碼配置bean的時候),使用類型安全并且比xml更為強大的JavaConfig。
也就是自己寫的盡量使用自動配置,他人的(第三方)使用JavaConfig
主要通過兩個角度來實現自動化配置
組件掃描(component scanning):Spring會自動發現應用上下文所創建的Bean
自動裝配(autowiring):Spring會自動滿足bean之間的依賴
總共分為三步:
第一步,將要使用的Bean添加上@Component注解
package stereo_autoconfig.soundsystem; import org.springframework.stereotype.Component; /** * Create by cuixin on 2018/8/26 **/ @Component public class SgtPeppers implements CompactDisc { private String title = "Sgt.Peppers"s Lonely Hearts Club Band"; private String artist = "The Beatles"; @Override public void play() { System.out.println("Play "+title+" by "+ artist); } }
第二步,通過@ComponentScan注解來掃描指定包及其子包中帶有@Component注解的類
package stereo_autoconfig.soundsystem; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * Create by cuixin on 2018/8/26 * 通過@ComponentScan注解啟動組件掃描, * 默認掃描所在包及其子包中帶有@Component注解的類 **/ @Configuration @ComponentScan public class CDPlayerConfig { }
第三步,通過@ContextConfiguration配置上下文信息,也就是聲明第二步中使用配置類
package stereo_autoconfig.soundsystem; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.assertNotNull; /** * Create by cuixin on 2018/8/26 **/ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CDPlayerConfig.class) public class CDPlayerTest { @Autowired private CompactDisc cd; @Test public void cdShouldNotBeNull() { assertNotNull(cd); } }2.2.2 為組件掃描的bean命名
默認bean的id是將類名的第一個字母小寫,比如上面的bean的ID就是sgtPeppers.
如果想要指定不同的ID,只需將值傳給@Component注解。
@Component("lonelyHeartClub") public class SgtPeppers implements CompactDisc { ... }2.2.3 設置組件掃描的基礎包 方法一:基于String類型指定基礎包.
Spring實戰中說這種方式是類型不安全的,我使用IDEA重命名包時,只有在Refactor時選擇Rename Package才會更改@ComponentScan中的String值,所以才說這是不安全的。
@ComponentScan默認的掃描的是所在包及其子包,如果你掃描其他包,或者想掃描多個包,應該怎么設置呢?指定不同的基礎包
@Configuration //方式一,指定一個,通過設置value屬性 @ComponentScan("stereo_autoconfig.soundsystem") public class CDPlayerConfig { } @Configuration //方式二,指定一個,通過設置basePackages屬性 @ComponentScan(basePackages = "stereo_autoconfig.soundsystem") public class CDPlayerConfig { } @Configuration//方式三,指定多個,通過設置basePackages為數組 @ComponentScan(basePackages = {"stereo_autoconfig.soundsystem", "stereo_autoconfig.video"}) public class CDPlayerConfig { }方法二:基于包中所含的類或接口來指定基礎包
@Configuration @ComponentScan(basePackageClasses = {CompactDisc.class, Video.class}) public class CDPlayerConfig { }
當然為了重構時刪除接口及相關類,你可以在包下面創建一個空標記接口(Marker Interface),專門用來指定基礎包。
public Interface SoundSystemMarkerInface{ } @Configuration @ComponentScan(basePackageClasses = {SoundSystemMarkerInface.class, Video.class}) public class CDPlayerConfig { }2.2.4 通過為bean添加注解實現自動裝配
通過@ComponentScan,我們已經可以掃描得到Bean,但是如何裝配這個Bean依賴的另一個bean呢?這就是自動裝配解決的問題了。
簡單來說,自動裝配就是讓Spring自動滿足bean依賴的一種方法。
@Component public class CDPlayer implements MediaPlayer { private CompactDisc cd; @Autowired public CDPlayer(CompactDisc cd){ this.cd = cd; System.out.println("構造器 自動裝配"); } @Override public void play() { cd.play(); } @Autowired public void setCompactDisc(CompactDisc cd){ this.cd = cd; System.out.println("Setter方法 自動裝配"); } @Autowired(required = false) public void insertDisc(CompactDisc cd){ this.cd = cd; System.out.println("其他方法 自動裝配"); } }
package stereo_autoconfig.soundsystem; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.assertNotNull; /** * Create by cuixin on 2018/8/26 **/ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CDPlayerConfig.class) public class CDPlayerTest { @Autowired private CompactDisc cd; @Autowired private MediaPlayer player; @Test public void cdShouldNotBeNull() { assertNotNull(cd); } @Test public void play(){ player.play(); } }
不管是構造器,Setter方法還是其他的方法,Spring都會去嘗試滿足方法參數上所聲明的依賴。上面依次會先執行構造器方法,
然后按照出現代碼順序執行其他自動注入方法。所以上面的輸出是
構造器 自動裝配
Setter方法 自動裝配
其他方法 自動裝配
第一點,假如有且只有一個bean匹配依賴需求的話,那么這個bean就會被裝配進來。
第二點,如果沒有匹配的bean,那么在應用上下文創建的時候spring會拋出一個異常。
為了避免異常的出現,可以將@AutoWired的required屬性設置為false。但這可能導致這個bean處于未轉配狀態,使用的使用需要判斷是否為空。
第三點,如果出現多個bean滿足依賴關系的話,spring的@AutoWired自動裝配也會拋出異常,因為他們不知道選哪一個
當使用第三方庫中的組件裝配到你的應用中,在這種情況下,是沒有辦法在它的類上添加@ComponentScan和@AutoWired注解的,因此就不能使用自動化裝配方案了。
JavaConfig比xml的優勢:更為強大,類型安全,并且對重構友好。
盡管不是必須的,但通常會將JavaConfig放到多帶帶的包中,使他與其他的應用程序邏輯分離開來。
步驟:使用@Configuration創建配置類,并使用帶有@Bean的方法聲明bean,最后通過@ContextConfiguration來創建上下文
package stereo_javaconfig.soundsystem; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Create by cuixin on 2018/8/26 **/ @Configuration //創建配置類 public class CDPlayerConfig { @Bean //通過bean注解來聲明簡單的bean public CompactDisc compactDisc(){ return new SgtPeppers(); } @Bean(name = "cdPlayer") //bean id默認使用的方法名,使用方法參數實現注入,最優方法,可以將CompactDisc放在其他配置類中 public CDPlayer cdPlayer(CompactDisc compactDisc){ return new CDPlayer(compactDisc); } // @Bean(name = "cdPlayer2") // //bean id默認使用的方法名,引用創建bean的方法實現注入,spring會攔截所有compactDisc()調用, // // 確保按照規定(single,request,session)使用正確的bean,而不是簡單地每次調用都生成一個 // public CDPlayer cdPlayer2(){ // return new CDPlayer(compactDisc()); // } }
package stereo_javaconfig.soundsystem; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import stereo_javaconfig.soundsystem.*; import static org.junit.Assert.*; /** * Create by cuixin on 2018/8/26 **/ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CDPlayerConfig.class) public class CDPlayeTest { @Autowired private MediaPlayer player; @Test public void player(){ player.play(); } }2.4 通過xml裝配Bean(略)
只是維護早先代碼的時候你才會用到這個。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76965.html
摘要:如果這個類的方法有修飾,就成為第二種的裝配方式代碼生成要自動裝配的類要保留默認構造函數,需要裝配的屬性使用來裝配。顯示裝配分為兩種,一種是代碼裝配,一種是裝配。和相比,上面這種形式的中的是調用默認構造函數生成的。 Bean的自動裝配 通過@ComponentScan掃描發現將要裝配到ApplicationContext中的Bean。@ComponentScan中如果沒有寫包名,那么默...
摘要:入門篇學習總結時間年月日星期三說明本文部分內容均來自慕課網。主要的功能是日志記錄,性能統計,安全控制,事務處理,異常處理等等。 《Spring入門篇》學習總結 時間:2017年1月18日星期三說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:https://github.com/zccodere/s...個人學習源碼:https://git...
摘要:前言在的第二篇中主要講解了模塊的使用容器創建對象的問題,模塊主要是解決對象的創建和對象之間的依賴關系,因此本博文主要講解如何使用容器來解決對象之間的依賴關系回顧以前對象依賴我們來看一下我們以前關于對象依賴,是怎么的歷程直接對象在最開始,我們 前言 在Spring的第二篇中主要講解了Spring Core模塊的使用IOC容器創建對象的問題,Spring Core模塊主要是解決對象的創建和...
摘要:的依賴關系,根據依賴關系配置完成之間的裝配。的行為信息,如生命周期范圍及生命周期各過程的回調函數。使用該種裝配模式時,優先匹配參數最多的構造函數。如果提供了默認的構造函數,則采用否則采用進行自動裝配。 點擊進入我的博客 1 Spring容器與Bean配置信息 Bean配置信息 Bean配置信息是Bean的元數據信息,它由一下4個方面組成: Bean的實現類 Bean的屬性信息,如數...
閱讀 3196·2021-11-18 10:02
閱讀 1446·2021-10-12 10:08
閱讀 1239·2021-10-11 10:58
閱讀 1269·2021-10-11 10:57
閱讀 1167·2021-10-08 10:04
閱讀 2121·2021-09-29 09:35
閱讀 773·2021-09-22 15:44
閱讀 1269·2021-09-03 10:30