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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

四、spring中高级装配(2)

發布時間:2024/4/15 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 四、spring中高级装配(2) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? 這個是接著上一篇寫的,這章內容較多,分開來記錄一下。。。

三、處理自動裝配的歧義性

? 自動裝配讓spring完全負責bean引用注入到構造參數和屬性中,不過,僅有一個bean匹配所需的結果時,自動裝配才是有效的。如果不僅有一個bean能夠匹配的話,這種歧義性會阻礙spring自動裝配屬性、構造參數或方法參數。雖然這種歧義性十分罕見,但是我看了spring解決方法后,感覺spring提供的是一種這類問題的解決辦法,顯然在這里主要學習的是這種解決此類問題的思想。

//這里是提供了這種特殊情況的demo,有一個方法,需要自動裝配Dessert接口 @Autowired public void setDessert(Dessert dessert){this.dessert = dessert; } //但是這個Dessert接口卻有三個實現類,這就有點尷尬了,spring自動裝配的時候到底要裝配哪個實現類呢..... spring會報NoUniqueBeanDefinitionException錯誤的 @Component public class Cake implements Dessert{......}@Component public class Cookies implements Dessert{......}@Component public class IceCream implements Dessert{......}//使用@Primary 注解標注首選bean @Primary @Component public class IceCream implements Dessert{......}<bean id="iceCream" class="com.desserteater.IceCream" primary="true" />//但是兩個同時加上@Primary注解呢!!!spring中會有@Qualifier注解 @Autowired @Qualifier("iceCream") public void setDessert(Dessert dessert){this.dessert = dessert; } //但是這種方式使用的是bean ID,限制符與要注入的bean是緊耦合的,對類名稱的改動都會導致限定符失效,但是spring中允許為bean設置自己的限定符 @Component @Qualifier("cold") public class IceCream implements Dessert{......}@Autowired @Qualifier("cold") public void setDessert(Dessert dessert){this.dessert = dessert; }//但是如果是兩個實現類具有相同特點的限制符呢!!!這個考慮的也太全面了吧,程序員就是要有這種精神的,哈哈哈,就是下面這種情況呢..... @Component @Qualifier("cold") @Qualifier("creamy") public class IceCream implements Dessert{......}@Component @Qualifier("cold") @Qualifier("fruity") public class Popsicle implements Dessert{......}//Java 中不允許出現在同一個條目上出現相同類型的多個注解的,唉,終極辦法:自定義限制符注解,這個好牛叉牛叉... //這個對應著就是@Qualifier("cold") @Target({ElementType.CONSTRUCAOR, ElementType.FILELD, ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier Public @interface Cold{}//這個對應著就是@Qualifier("creamy") @Target({ElementType.CONSTRUCAOR, ElementType.FILELD, ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier Public @interface Creamy{}//這個對應著就是@Qualifier("fruity") @Target({ElementType.CONSTRUCAOR, ElementType.FILELD, ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier Public @interface Fruity{}//大功告成,這就徹底解決那個問題了,你在有多少的我也不怕了,嘿嘿嘿,完美的解決這個問題了,spring中太美妙了,這種思想真的讓人受益匪淺 @Component @Cold @Creamy public class IceCream implements Dessert{......}@Component @Cold @Fruity public class Popsicle implements Dessert{......}@Autowired @Cold @Creamy public void setDessert(Dessert dessert){this.dessert = dessert; }

四、bean的作用域

? ?在默認情況下,spring應用上下文中所有的bean都是以單例的形式創建的,也就是說,不管給定的一個bean被注入到其他bean多少次,每次所注入的都是同一個實例。大多數情況下,單例bean是很理想的方案。初始化和垃圾回收對線實例所帶來的成本只留給一些小規模的任務,在這些任務中,讓對象保持無狀態并且在應用中反復用這些對象可能并不合理。

spring中為解決這個問題,定義了多種作用域,可以基于這些作用域創建bean:

1)單例(Singleton):在整個應用中,只創建bean的一個實例

2)原型(Prototype):每次注入或者通過spring應用上下文獲取的時候,都會創建一個新的bean的實例

3)會話(Session):在web應用中,為每個會話創建一個bean實例

4)請求(Request):在web應用中,為每個請求創建一個bean實例

//Prototype 原型作用域的配置方式 @Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class Notepad{......}<bean id="notepad" class="com.myapp.Notepad" scope="prototype" />//Session 會話和 Request 請求作用域 //在電商領域的 處理購物車bean 會話作用域是最合適的 @Component @Scope( value=WebApplicationContext.Scope.SESSION, ProxyMode=ScopedProxyMode.INTERFACES) Public ShoppingCart cart(){......}@Component Public class StoreService(){//StoreService是一個單例bean,會在spring應用上下文加載的時候創建,當它創建的時候,會試圖將ShoppingCart bean注入到set方法中,但是ShoppingCart bean是會話作用域,此時并不存在,直到某個用戶進入系統,創建會話之后才會出現ShoppingCart 的實例 @Autowiredpublic void setShoppingCart(ShoppingCart shoppingCart){this.shoppingCart = shoppingCart;} } /* 這里需要詳細講解一下ProxyMode 系統中,會有多個ShoppingCart 的實例,每個用戶一個,我們希望當StoreService處理購物車的時候,它所使用的ShoppingCart 實例恰好是當前會話所對應的那一個spring并不會將實際的ShoppingCart bean注入到StoreService中,spring會注入一個到ShoppingCart bean的代理,這個代理會暴露于ShoppingCart 相同的方法,StoreService會認為它就是一個購物車當StoreService 調用 ShoppingCart 的方法時,代理會對其進行懶解析并調用委托給會話作用域內真正的ShoppingCart bean這個東西好牛氣的樣子,這里涉及到了代理模式 *///注意:ScopedProxyMode.INTERFACES 表明這個代理要實現ShoppingCart接口,并將調用委托給實現bean //注意:ScopedProxyMode.TARGET_CLASS 實現的是一個具體的類的話,spring必須使用CGLib 來生成基于類的代理//XML中實現作用域的配置 這里用到了AOP Spring中面向切面 <bean id="cart" class="com.myapp.ShoppingCart"><aop:scoped=proxy /> //spring會默認CGLib創建目標類的代理 </bean>//這種 proxy-target-class="false" spring會創建基于接口的代理 <bean id="cart" class="com.myapp.ShoppingCart"><aop:scoped=proxy proxy-target-class="false" /> </bean>

?五、運行時值注入

這節主要講的就是spring中的表達式語言SpEL,其他的基本上沒有特別重要的,值得思考的知識點。

spring提供了兩種在運行時求值的方式:

(1)屬性占位符(Property placeholder)

(2)Spring 表達式語言(SpEL)

屬性占位符的語法是:${.....}

主要來說一下Spring 表達式語言(SpEL)

1、SpEL擁有很多特性,主要包括:

1)使用bean的ID來應用bean

2)調用方法和訪問對象的屬性

3)對值進行算術、關系和邏輯運算

4)正則表達式匹配

5)集合操作

2、SpEL樣例

1)表示String值、浮點數、Boolean值

#{3.14159}

#{9.87E4}? 對應著 98700

#{“hello”}

#{true}

2)引用bean、屬性和方法

#{sgtPeppers}

#{sgtPeppers.artist}

#{sgtPeppers.selectArtist()}

#{sgtPeppers.selectArtist().toUpperCase()}

#{sgtPeppers.selectArtist()?.toUpperCase()}? 避免出現空值,出現?避免出現空值

3)在表達式中使用類型

T{java.lang.Math}

T{java.lang.Math}.PI

T{java.lang.Math}.random()

4)SpEL運算符

#{2*T{java.lang.Math}.PI*circle.radius}

#{T(java.lang.Math).PI*circle.radius^2}

#{disc.title + 'by' + disc.artist}

#{counter.total == 100}

#{counter.total eq 100}

#{score > 100 ? "winner" : "loser"}

5)計算正則表達式

#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9._]+\\.com'}

6)計算集合

#{jukebox.songs[4].title}

#{jukebox.songs[T(java.lang.Math).random * jukebox.songs.size()].title}

#{jukebox.songs.?[artist eq 'Aerosmith']} 過濾歌曲,得到所有屬性為Aerosmith的歌曲的小的集合

#{jukebox.songs.^[artist eq 'Aerosmith']}? 查詢集合中第一個屬性為Aerosmith的歌曲

#{jukebox.songs.![title]} 投影運算符,將集合中的特定的屬性放到一個新集合中去

#{jukebox.songs.?[artist eq 'Aerosmith']}.![title] 混合使用,把作者是Aerosmith的title屬性放到一個集合中去

轉載于:https://www.cnblogs.com/ssh-html/p/9656504.html

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

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

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