日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

spring(2)装配Bean

發布時間:2023/12/3 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring(2)装配Bean 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【0】README 0)本文部分文字描述轉自:“Spring In Action(中/英文版)”,旨在review ?spring(2)裝配Bean?的相關知識; 1)在spring中,對象無需自己查找或創建與其所關聯的其他對象。相反,容器負責把需要相互協作的對象引用賦予各個對象; 2)裝配:創建應用對象之間協作關系的行為通常稱為裝配,這也是依賴注入(DI)的本質(干貨——裝配是依賴注入的本質); 3)可以預熱一下:在Spring中裝配bean有多種方式:配置Spring容器最常見的三種方法;
【1】Spring配置的可選方案 1)Spring容器作用:負責創建應用程序中的bean 并通過DI 來協調對這些對象之間的關系; 2)當描述bean 如何進行裝配時,Spring提供了3種主要的裝配機制(mechanism):
  • m1)在XML中進行顯式配置;
  • m2)在java中進行顯式配置;
  • m3)隱式的bean 發現機制和自動裝配;
Attention)
  • A1)Spring的配置風格是可以互相搭配的,所以你可以選擇使用XML 裝配一些bean,使用Spring基于java 的配置(JavaConfig)來裝配另一些bean,而剩下的bena可以讓Spring自動發現;
  • A2)而原書作者建議:盡可能地使用自動配置的機制;而必須要顯示配置bean的時候,原書作者推薦類型安全并且比XML 更加強大的 JavaConfig;
  • A3)最后,只有當你想要使用便利的xml 命名空間,并且在 JavaConfig 中沒有同樣的實現時,才應該使用 XML;
【2】自動化裝配Bean(Spring最強大的裝配技術) 1)intro:Spring從兩個角度來實現自動化裝配: 1.1)組件掃描:Spring會自動發現應用上下文中所創建的bean; 1.2)自動裝配:Spring自動滿足bena之間的依賴;
【2.1】創建可被發現的Bean 1)以CD作為DI 如何運行提供的荔枝。如果你不將CD 插入(注入)到CD 播放器中,那么CD 播放器其實是沒有太大用處的; 2)創建Disc(唱片)接口和具體的唱片
對以上代碼的分析(Analysis): A1)component注解表明:該類會作為組件類,并告知spring要為這個類創建bean.(干貨——@Component注解的作用) A2)組件掃描默認是不啟用的。我們需要顯式配置一下spring, 從而命令它去尋找帶有@Component注解的類,并為其創建bean; 3)利用 @ComponentScan 注解啟用了組件掃描 package com.spring.chapter2;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration @ComponentScan public class CDPlayerConfig { } 對以上代碼的分析(Analysis): A1)類CDPlayerConfig?通過 java 代碼定義了Spring的裝配規則; A2)類CDPlayerConfig?并沒有顯式地聲明任何bean, 只不過它使用了 @ComponentScan 注解,這個注解能夠在Spring中啟用組件掃描;(干貨——@ComponentScan注解的作用) A3)@ComponentScan注解:默認會掃描配置類相同的包。因為CDPlayerConfig?位于?com.spring.chapter2,那所以Spring將會掃描這個包及其所有子包,查找帶有 @Component注解的類; Attention)也可以使用XML來啟用組件掃描; <context:component-scan base-package="com.spring.chapter2"> 4)接下來創建測試用例(JUnit測試);
對以上代碼的分析(Analysis): A1)該測試用例使用了 Spring 的 SpringJUnit4ClassRunner:以便在測試開始的時候自動創建 Spring的應用上下文; A2)注解@ContextConfiguration:會告訴它需要在 CDPlayerConfig中加載配置;因為CDPlayerConfig 類中包含了@ComponentScan, 所以最終的應用上下文應該包含JayChou bean;(干貨——@ContextConfiguration注解的作用)
【2.2】為組件掃描的bean命名(自定義bean 名稱) 1)默認的名稱是:將類的第一個字母改為小寫,就是bean 名稱; 2)自定義bean名稱:將期望的id 作為值傳遞給 @Component注解;如? @Component("jay chou") public class JayChou implements Disc{ 3)還有一種為bean 命名的方式,這種方式不使用 @Component注解,而使用java依賴注入規范中提供的 @Named注解來設置bean id: @Named("jay chou") public class JayChou implements Disc{ Attention) 注解 @Named == 注解 @Component:在大多數case下,他們是可以互換的,但更喜歡用 Component; (干貨——@Named注解的作用)

【2.3】設置組件掃描的基礎包 1)problem+solution: 1.1)problem:@ComponentScan注解會按照配置類(如CDPlayerConfig?)所在的包作為基礎包進行掃描,但是,如果想掃描不同的包,該怎么做? 1.2)solution:為了指定不同的基礎包,需要做的就是在 @ComponentScan 的value屬性中指明包的名稱: @Configuration @ComponentScan("com.spring.chapter1") public class CDPlayerConfig { } 1.2.1)如果想更加清晰地表明想要設置的基礎包,通過basePackage屬性進行配置: @Configuration @ComponentScan(basePackage="com.spring.chapter1") public class CDPlayerConfig { } 1.2.2)當然也可以設置多個基礎包 @Configuration @ComponentScan(basePackage={"com.spring.chapter1", "com.spring.chapter2"}) public class CDPlayerConfig { } 2)problem+solution: 2.1)problem:在上面的荔枝中,所設置的 基礎包是String類型的;這種方法是類型不安全的 2.2)solution:@ComponentScan注解還提供了另外一種方法,那就是將其指定為包中所包含的類或接口: @Configuration @ComponentScan(basePackageClasses={CDPlayer.class, DVDPlayer.class}) public class CDPlayerConfig { } Attention)basePackage 被替換為了 basePackageClasses;而basePackageClasses 屬性設置的數組包含了類。這些類所在的包將作為 組件掃描的基礎包;(這就會掃描多個包了 ) 3)我們需要一種方法:能夠將組件掃描得到的bean 和 他們的依賴裝配在一起,自動裝配就可以完成這項任務; (干貨——引入自動裝配的概念)
【2.4】通過為bean 添加注解實現自動裝配 1)自動裝配定義:自動裝配就是讓Spring自動滿足bean依賴的一種方法,在滿足依賴的過程中,會在Spring 應用上下文中尋找匹配某個bean需求的其他bean;(干貨——自動裝配定義) 2)@Autowired注解: 為了聲明要進行自動裝配,我們可以借助Spring 的?@Autowired注解; 3)@Autowired注解的意義:它在構造器上添加了@Autowired注解,這表明當Spring創建了 CDPlayer bean的時候,會通過這個構造器來進行實例化并且會傳入一個Disc類型的bean;(干貨——@Autowired注解的作用 public class CDPlayer implements MediaPlayer{private Disc disc;@Autowiredpublic CDPlayer(Disc disc) {this.disc = disc;}public void play() {disc.play();} } 對以上代碼的分析(Analysis): A0)上述第4行代碼的 @Autowired:該注解表明 當Spring創建CDPlayer bean 的時候,會通過這個構造器來進行實例化并且會傳入一個可設置給 Disc 類型的bean; A1)注解@Autowired 不僅能夠用在構造器上,還能用在屬性的setter方法上; @Autowiredpublic void setDisc(Disc disc) {this.disc = disc;} A2)實際上, 注解 @Autowired 可以用在類的任何方法上; 4)如果沒有匹配的bean,那么在應用上下文創建的時候,Spring會拋出一個異常; 4.1)為了避免拋出異常,可以將required設置為 false:將required 屬性設置為false時,Spring 會嘗試執行自動裝配,但是如果沒有匹配的bean的話,Spring將會讓這個bean 處于未裝配的狀態;? @Autowired(required=false)public CDPlayer(Disc disc) {this.disc = disc;} 4.2)如果有多個bean滿足依賴關系的話,Spring將會拋出異常,表明沒有明確指定要選擇哪個bean 進行自動裝配;
5)注解@Inject:該注解來源于java 依賴注入規范,該規范同時還為我們定義了 @Named 注解;在自動裝配中,Spring同時支持 @Inject ?和 @Autowired,在大多數cases下,他們是可以互換的 ;(干貨——@Inject注解的作用)
【2.5】驗證自動裝配

【3】通過java 代碼裝配bean 1)有時候自動化配置方案行不通,因此需要明確配置Spring;如,你想要將第三方庫中的組件裝配到你的應用中,在這種case下,是沒有辦法在它的類上添加 @Component 和 @Autowired 注解的,因此就不能使用自動化裝配的方案了; 2)所以就要采用顯式裝配bean方式,有兩種方案可以選擇(scheme): java 和xml;原書作者建議:在進行顯式配置時,JavaConfig 是更好的方案,因為它更為強大,類型安全并且對重構友好;
【3.1】創建配置類 1)創建JavaConfig類的關鍵:在于為其添加 @Configuration注解,@Configuration注解表明這個類是一個配置類,該類應該包含在Spring應用上下文中如何創建bean的細節 ;(不能再干貨——@Configuration注解的作用) 2)由于是顯式配置,所以要remove掉 @ComponentScan注解;
【3.2】聲明簡單的bean 1)如何聲明:要在 JavaConfig中聲明bean,我們需要編寫一個方法,這個方法會創建所需類型的實例,然后給這個方法添加 @Bean注解; @Beanpublic Disc jaychou() {return new JayChou();}對以上代碼的分析(Analysis):@Bean注解會告訴Spring 這個方法將會返回一個對象,該對象要注冊為 Spring應用上下文中的bean;方法體中包含了最終產生bean實例的邏輯;(干貨——@Bean注解的作用) 2)默認case下: bean 的ID 將與帶有@Bean注解的方法名是一樣的;本例中,其ID==jaychou; 2.1)可以自定義bean的ID: @Bean(name="our jaychou")public Disc jaychou() {return new JayChou();} 【3.3】借助JavaConfig實現注入 1)problem+solution 1.1)problem:前面聲明的 JayChou(Disc)自身沒有其他依賴;現在要聲明CDPlayer bean,它依賴與 JayChou,那么在 JavaConfig中,要如何將它們裝配在一起呢? 1.2)solution:在 JavaConfig中裝配bean的最簡單方式就是引用創建bean的方法。如下面就是一種聲明 CDPlayer的可行方法: // defined in CDPlayer. @Bean(name="our jaychou")public Disc jaychou() {return new JayChou();} @Beanpublic CDPlayer cdPlayer() {return new CDPlayer(jaychou());} 對以上代碼的分析(Analysis): A1)cdPlayer()方法與jaychou()方法有些區別:在這里并沒有使用默認的構造器構建實例,而是調用了需要傳入 Disc 對象 的構造器來創建CDPlayer實例; A2)看起來 Disc 是通過?jaychou()方法得到的,但case并非總是如此:因為jaychou()方法上添加了 @Bean注解,Spring將會攔截所有對它的調用,并確保直接返回該方法所創建的bean,而不是每次都對其進行調用;(干貨中的干貨——也即是對jaychou方法的多次調用都只會返回同一個bean,而不是多個bean); 看個荔枝) cdPlayer方法返回的CDPlayer的Disc 對象 與?anotherPlayer方法返回的CDPlayer的Disc 對象是同一個; (干貨——在軟件領域中,多個播放器player可以使用同一張唱片jaychou)?
@Beanpublic CDPlayer cdPlayer() {return new CDPlayer(jaychou());}@Beanpublic CDPlayer anotherPlayer() {return new CDPlayer(jaychou());} 對以上代碼的分析(Analysis):? A1)默認情況下,Spring中的bean 都是單例的,我們并沒有必要為第2個CDPlayer bena創建相同的 JayChou 唱片; A2)總之一句話: Spring會攔截對?jaychou()方法的調用并確保返回的是 Spring所創建的bean,也就是Spring本身首次調用jaychou()方法所創建的bean; Attention) A1)需要提醒的是,我們在這里使用CDPlayer的構造器實現了 DI 功能,但是我們完全可以采用其他風格的DI 配置;比如,如果想通過Setter 方法注入Disc的話,代碼像這個樣子: @Beanpublic CDPlayer cdPlayer(Disc disc) {CDPlayer cdPlayer = new CDPlayer(disc);cdPlayer.setDisc(disc);return cdPlayer;} A2)帶有@Bean 注解的方法可以采用任何必要的java 功能來產生bean實例。構造器和Setter 方法只是 @Bean方法的兩個簡單樣例;

2)對@bean注解的另外一種理解方式

@Bean public CDPlayer cdPlayer(Disc disc) {return new CDPlayer(disc); }

對以上代碼的分析(Analysis):當Spring 調用cdPlayer()創建CDPlayer bean的時候,它會自動裝配一個Disc 到配置方法中。通過這種方式引用其他的bean 通常是 最佳的選擇,因為它不會要求將 Disc 聲明到同一個配置類中,在這里甚至沒有要求 Disc 必須要在 JavaConfig中聲明,實際上它可以通過組件掃描功能自動發現或通過XML 來進行配置;




【4】通過XML 裝配bean 【4.1】創建XML 配置規范 1)在使用JavaConfig的時候,要創建一個帶有 @Configuration注解的類,而在XML配置中,這意味著要創建一個XML 文件,并且要以<beans>元素為根;<beans>是spring-benas模式中的一個元素; 2)最為簡單的Spring XML 配置如下圖所示: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context"> <!-- configuration details go here --> </beans> 對以上代碼的分析(Analysis):使用XML時,需要在配置文件的頂部聲明多個 XML 模式(XSD)文件,這些文件定義了配置Spring的XML 元素; Supplement)借助Spring Tool Suite 創建XML 配置文件:創建和管理Spring XML 配置文件的一種簡便方式是使用Spring Tool Suit;(原書作者又一次打了ad,覺得有用的,可以down 下來玩玩)
【4.2】聲明一個簡單的<bean> 1)使用spring-beans模式中的另外一個元素:<bean>;><bean>元素類似于JavaConfig 中的 @Bean注解; 2)我們按照如下方式聲明 Disc bean:(這里聲明了一個很簡單的bean,創建這個bean的類通過class 屬性來指定,并且要使用全限定的類名) <bean class="com.spring.chapter1.JayChou" /> 對以上代碼的 分析(Analysis): A1)默認的bean id :根據全限定類名來進行命名,在本例中default id == com.spring.chapter1.JayChou#0,#0是一個計數的形式,用來區分相同類型的其他bean; A2)自定義bean id: <bean id="mydiy" class="com.spring.chapter1.JayChou" /> Attention) A1)減少繁瑣: 為了減少xml 中繁瑣的配置,只對那些需要按名字引用的bean 進行明確的命名;(比如你需要將對它引用注入到另一個bean中);(干貨——引入減少繁瑣) A2)當Spring發現這個 <bean>元素時,它將會調用 其默認構造器來創建bean;在XML配置中,bean的創建更加被動; A3)在這個簡單的<bean>聲明中,我們把bean的類型以字符串的形式設置在了 class屬性中,誰知道它是對的還是不對的。。為了檢查該字符串是否是實際的類型,借助Spring Tool Suit檢查XML的合法性;(感覺這個原書作者在打ad 一樣,hh); 【4.3】借助構造器注入初始化bean 1)在XMl中聲明DI時,具體到構造器注入,有兩種配置方案(scheme): s1)<constructor-arg>元素; s2)使用spring3.0 所引入的 c-命名空間; 2)構造器注入bean引用 scheme1)通過XML配置 來實現 “CDPlayer 類需要依賴(引用) Disc的實現類” 的需求;
<bean id="cdPlayer" class="com.spring.chapter2.CDPlayer"><constructor-arg ref="jaychou" /> </bean> <bean id="jaychou" class="com.spring.chapter2.JayChou"> </bean> scheme2)通過c-命名空間 來實現 “CDPlayer 類需要依賴(引用) Disc的實現類” 的需求; step1)要使用spring 的c-命名空間的話,必須要在XML 的頂部聲明其模式,如下所示: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> ... </beans> step2)使用c-命名空間來聲明構造器參數: <bean id="cdPlayer" class="com.spring.chapter2.CDPlayer" c:cd-ref="jaychou" /> Attention)下圖描述了這個屬性名是如何組合而成的?
problem+solution) problem) solution)我們使用參數在整個參數列表中的位置信息: <bean id="cdPlayer" class="com.spring.chapter2.CDPlayer" c:_0-ref="jaychou" /> 對以上代碼的分析(Analysis):我們將參數的名稱替換為 “0”(因為數字不能開頭,所以加了下劃線作為前綴);使用索引(_0,_1,...)來識別構造器參數感覺比使用名字更好一些; 3)將字面量注入構造器中(即,構造器參數是String類型,而不是具體的java類型)
3.1)通過XML來裝配 <bean id="leehom" class="com.spring.chapter2.Leehom"><constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" /><constructor-arg value="The Beatles" /> </bean>3.2)通過c-命名空間來裝配 <bean id="leehom"class="com.spring.chapter2.Leehom"c:_title="Sgt. Pepper's Lonely Hearts Club Band"c:_artist="The Beatles" /> 4)裝配集合:這種case下,<constructor-arg>能夠實現,而c-命名空間是不能夠實現的;
solutions)
s1)最簡單的方法是將列表設置為null:
s2)更好的解決方法是提供給一個磁道名稱的列表:使用 <list>元素將其聲明為一個列表:
s3)當然了,我們也可以使用<ref>元素替代 <value>,實現bean引用列表的裝配:
看個荔枝)通過XML配置 裝配集合 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="leehom" class="com.spring.chapter2.Leehom"c:_0="十八般武藝" c:_1="Leehom Wang"><constructor-arg><list><value>Sgt. Pepper's Lonely Hearts Club Band</value><value>With a Little Help from My Friends</value><value>Lucy in the Sky with Diamonds</value><value>Getting Better</value><value>Fixing a Hole</value><!-- ...other tracks omitted for brevity... --></list></constructor-arg></bean> </beans> public class Leehom implements Disc {private String title;private String artist;private List<String> tracks;public Leehom() {}public Leehom(String title, String artist, List<String> tracks) {this.title = title;this.artist = artist;this.tracks = tracks;}public void setTitle(String title) {this.title = title;}public void setArtist(String artist) {this.artist = artist;}public void setTracks(List<String> tracks) {this.tracks = tracks;}public void play() {System.out.println("Playing " + title + " by " + artist);for (String string : tracks) {System.out.println("-track: " + string);}}@Overridepublic String getName() {return artist;} }

Attention)我們也可以用同樣的方式使用<set>元素:<list>和 <set>的元素區別在于:當Spring創建要裝配的集合時,所創建的是 java.util.Set 還是 java.util.List;如果是Set的話,那么重復的值都會被忽略掉,存放順序也不會得以保證保證;不過無論在哪種case下,都可以用 <set> 或 <List> 來裝配 List or Set 設置 數組;

【4.4】設置屬性(如何使用Spring XML實現屬性注入) 1)該選擇構造器注入還是屬性注入呢? 作為一個通用的規則, 原書作者傾向于對強依賴使用構造器注入,而對可選性的依賴使用屬性注入;
2)Spring為<constructor-arg> ?元素提供了c-命名空間作為替代方案,同樣,Spring提供了更加簡潔的p-命名空間,作為<property>元素的替代方案; 2.1)為了啟用p-命名空間,必須要在 XML 文件中與其他的命名空間一起對其進行聲明;
2.2)利用p-命名空間,按照以下方式裝配disc屬性;

3)將字面量注入到屬性中
3.1)新的Leehom 類如下所示:
3.2)通過<property>元素的value屬性注入
3.3)通過spring的p-命名空間來實現注入
對以上代碼的分析(Analysis): A1)與c-命名空間一樣,裝配bean 引用與裝配字面量的唯一區別是: 是否帶有“-ref”后綴,如果沒有該后綴的話,所裝配的就是字面量(如String類型);(干貨——裝配bean 引用與裝配字面量的唯一區別是: 是否帶有“-ref”后綴,如果沒有該后綴的話,所裝配的就是字面量) A2)不能通過p-命名空間來裝配集合;但可以使用 Spring util-命名空間中的一些功能來簡化 Leehom bean; step1)需要在XML 中聲明util-命名空間及其模式
step2)util-命名空間所提供的功能之一是 <util:list>元素,它會創建一個 ?列表的bean;
step3)通過<util:list>元素創建了List bean,現在,我們將磁道列表 bean(tracklist) 注入到 Leehom 的tracks 屬性中;
Attention)<util:list>元素只是 util-命名空間中的多個元素之一。下表列出了 util-命名空間提供的所有元素:

【5】導入和混合配置(如何將自動化配置,JavaConfig以及XML 配置混合并匹配在一起) 【5.1】在JavaConfig 中引用XML 配置

Supplement)即是,CDPlayer ?bean通過 JavaConfig 來創建(裝配);而Disc的實現類 JayChou bean 通過 XML配置來創建(裝配);
【5.2】在XML配置中引用 JavaConfig


總結

以上是生活随笔為你收集整理的spring(2)装配Bean的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。