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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

第三章 最小化SpringXml 配置

發布時間:2023/12/20 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第三章 最小化SpringXml 配置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自動裝配(autowiring):有助于減少甚至消除<property>元素和<constructor-arg>元素,讓spring自動識別如何裝配Bean的依賴關系。

自動檢測(autodiscovery):比自動裝配更進一步,讓spring能夠自動識別哪些類需要被裝配成sping Bean ,從而減少對<bean>元素的使用。

3.1 自動裝配Bean屬性

3.1.1 4種類型的自動裝配

  byName——把與Bean的屬性具有相同的名字(或者ID)的其他Bean自動裝配到Bean對應的屬性中。如果沒有跟屬性的名字像匹配的Bean,則該屬性不進行裝配。

  byType——把與Bean的屬性具有相同類型的其他Bean自動裝配到Bean的對應屬性中,若果沒有跟屬性的類型相匹配的bean,則該屬性不被裝配。

  constructor——把與Bean的構造器入參具有相同類型的其他Bean自動裝配到Bean構造器的對應參數中。

  autodetect——首先嘗試使用constructor進行自動裝配,如果失敗,再嘗試使用byType進行自動裝配。

  byName自動裝配:

1 <!-- byName自動裝配 2 缺點:若是有多個音樂家需要裝配instrument屬性,則他們就會公用一個Saxopbone(即多個bean的屬性被同一個bean賦值) 3 --> 4 <!-- 先在容器中裝個樂器對象 --> 5 <bean id="instrument" class="com.springinaction.springidol.Saxophone"></bean> 6 <!--現在為音樂家kenny自動裝配上面instrument的樂器--> 7 <bean id="kenny" --> 8 class="com.springinaction.springidol.Instrumentalist" 9 autowire="byName"> 10 <property name="song" value="演員——薛之謙"></property> 11 </bean> 12 13 <bean id="kenny1" 14 class="com.springinaction.springidol.Instrumentalist" 15 autowire="byName"> 16 <property name="song" value="演員1——薛之謙"></property> 17 </bean> View Code

  byType自動裝配,容器中若是有同個類型的多個bean,自動裝配的時候,會出拋出異常(就像選擇性綜合征,多了不知選哪個了)NoUniqueBeanDefinitionException(不唯一bean定義異常,翻譯的可能不準確):

1 <!-- byType裝配 2 有兩個樂器:kenny bean就不知道要識別那個樂器裝配給自己, 3 會拋出異常NoUniqueBeanDefinitionException(非唯一bean定義異常-個人翻譯,可能不正確), 4 但是下面會出現提示: 5 org.springframework.beans.factory.UnsatisfiedDependencyException: 6 Error creating bean with name 'kenny' defined in class path resource [spring/springbean.xml]: Unsatisfied dependency expressed through bean property 'instrument': No qualifying bean of type [com.springinaction.springidol.Instrument] is defined: expected single matching bean but found 2: com.springinaction.springidol.Saxophone#0,com.springinaction.springidol.Guitar#0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.springinaction.springidol.Instrument] is defined: expected single matching bean but found 2: com.springinaction.springidol.Saxophone#0,com.springinaction.springidol.Guitar#0 7 Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.springinaction.springidol.Instrument] is defined: expected single matching bean but found 2: com.springinaction.springidol.Saxophone#0,com.springinaction.springidol.Guitar#0 8 --> 9 <!-- Saxophone類型的bean --> 10 <bean class="com.springinaction.springidol.Saxophone"></bean> 11 <!--Guitar類型的bean--> 12 <bean class="com.springinaction.springidol.Guitar"></bean> 13 14 <bean id="kenny" 15 class="com.springinaction.springidol.Instrumentalist" 16 autowire="byType"> 17 <property name="song" value="演員——薛之謙"></property> 18 </bean> View Code

  constructor自動裝配:

1 <!-- constructor 自動裝配 2 這個要求PoeticJuggler類中有一個構造器的參數是Sonnet29(他是--實現Poem的實現類)類型的 3 --> 4 <bean class="com.springinaction.springidol.Sonnet29"></bean> 5 6 <bean id="duke" 7 class="com.springinaction.springidol.PoeticJuggler" 8 autowire="constructor"/> View Code

?  autodetect混合裝配,就不介紹了。

  注:在測試代碼的時候,遇到了如下的SAXParseException異常:
Caused by: org.xml.sax.SAXParseException; lineNumber: 48; columnNumber: 45; 注釋中不允許出現字符串 "--"。
?? ?at ;
  這個是由于springbean.xml中的注釋<!-- 這里是注釋 -->除了開頭和結尾可以有"--"外,里面不能有第三個"--",不如:<!-- 這里是是--注釋 -->就會報上面的錯誤,這個一看就明白了。

3.1.2 默認自動裝配

  若果需要為Spring應用上下文中的額每一個Bean(或者其中大多數)配置相同的autowire屬性,那么可以要求spring為它所創建的所有Bean引用相同的自動裝配策略來簡化配置

3.2 使用注解裝配

  使用注解方式允許更細粒度的自動裝配,我們可以選擇性標注某一個屬性來對其應用自動裝配。spring容器默認禁用注解裝配,所以,在使用基于注解的自動裝配,我們需要在spring配置中啟用它。最簡單的啟用方式是使用spring的context命名空間配置中的<context:annotation-config>元素:

  spring的context命名空間:?xmlns:context="http://www.springframework.org/schema/context";

  ?xsi:schemaLocation的值中要加:http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd;這兩個東西(好像是約束,不知是啥)

  spring3支持幾種不同的用于自動裝配的注解:

  • spring自帶的@Autowierd注解;
  • JSR-330的@Inject注解;
  • JSR-250的@Resource注解;

3.2.1 使用@Autowired

@Autowired是:org.springframework.beans.factory.annotation包下的Autowired接口如下:

  

  @Autowired的裝配代碼,比如,在Instrumentalist類型的setInstrument上標注@Autowired:

1 //注入樂器 2 @Autowired 3 public void setInstrument(Instrument instrument) { 4 this.instrument = instrument; 5 } View Code

  在springbean.xml中:

1 <!-- Saxophone類型的bean --> 2 <!-- <bean class="com.springinaction.springidol.Saxophone"></bean> --> 3 <!--Guitar類型的bean(Instrument 樂器)--> 4 <bean class="com.springinaction.springidol.Guitar"></bean> 5 6 <bean id="kenny" 7 class="com.springinaction.springidol.Instrumentalist"> 8 <property name="song" value="演員——薛之謙"></property> 9 </bean> View Code

  測試結果,這時容器中只有一個樂器類型的bean:

1 //測試注解@Autowired 2 @Test 3 public void testAutowired() throws Exception { 4 5 Instrumentalist kenny = (Instrumentalist) ac.getBean("kenny"); 6 kenny.perform(); 7 kenny.getInstrument().play(); 8 9 } View Code

   當springbean.xml中有兩個樂器類型的bean時,會拋異常BeanCreationException,還是bean不唯一的問題:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kenny': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.springinaction.springidol.Instrumentalist.setInstrument(com.springinaction.springidol.Instrument); nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.springinaction.springidol.Instrument] is defined: expected single matching bean but found 2: com.springinaction.springidol.Saxophone#0,com.springinaction.springidol.Guitar#0:

1 <!-- Saxophone類型的bean,下面兩個bean同時存在的時候,會拋異常NoUniqueBeanDefinitionException --> 2 <bean class="com.springinaction.springidol.Saxophone"></bean> 3 <!--Guitar類型的bean(Instrument 樂器)--> 4 <bean class="com.springinaction.springidol.Guitar"></bean> 5 6 <bean id="kenny" 7 class="com.springinaction.springidol.Instrumentalist"> 8 <property name="song" value="演員——薛之謙"></property> 9 </bean> View Code

  上面就拋出異常;

  @Autowired可以在構造器上面和屬性上面(這里標注了就可以把setter方法刪掉了)都可以標注;

  當容器中沒有自動裝配的bean時,會拋出 NoSuchBeanDefinitionException(沒有這樣的bean定義異常):
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.springinaction.springidol.Instrumentalist.setInstrument(com.springinaction.springidol.Instrument); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springinaction.springidol.Instrument] found for
  這時候@Autowired(required=false)這樣裝配,自動裝配可選,容器中沒有改類型的bean,instrument值會是空:
 ? @Autowired(required=false)
?? ? private Instrument instrument;

  這時候拋異常會拋NullPointException;

  若是@Autowired注解用在構造器上時,只有一個構造器上required設置為true,其他使用@Autowired注解所標注的構造器只能將required屬性設置為false。

為解決上述問題,可以使用注解@Qualifier("guitar"),配置如下,這種配置和第二章中的<property name='instrument' ref='guitar'>原理其實應該差不多(個人覺得):

1 @Autowired(required=false) 2 @Qualifier("guitar") 3 private Instrument instrument; View Code 1 <bean id="saxophone" class="com.springinaction.springidol.Saxophone"></bean> 2 <!--Guitar類型的bean(Instrument 樂器)--> 3 <bean id="guitar" class="com.springinaction.springidol.Guitar"></bean> 4 5 <bean id="kenny" 6 class="com.springinaction.springidol.Instrumentalist"> 7 <property name="song" value="演員——薛之謙"></property> 8 </bean> View Code

  還可以如下進行配置:

1 @Autowired(required=false) 2 //@Qualifier("guitar") 3 private Instrument instrument; View Code 1 package com.springinaction.springidol; 2 3 import org.springframework.beans.factory.annotation.Qualifier; 4 5 /** 6 * 7 * @ClassName: Guitar 8 * @Description: 樂器:吉他 9 * @author mao 10 * @date 2017年3月19日 下午8:15:44 11 * 12 */ 13 @Qualifier("stringed") 14 public class Guitar implements Instrument { 15 16 public Guitar(){ 17 18 } 19 20 public void play() { 21 System.out.println("guitar guitar guitar"); 22 } 23 24 } View Code 1 <bean class="com.springinaction.springidol.Guitar"> 2 <qualifier value="stringed"></qualifier> 3 </bean> 4 5 <bean id="kenny" 6 class="com.springinaction.springidol.Instrumentalist"> 7 <property name="song" value="演員——薛之謙"></property> 8 </bean> View Code

測試了一下<qualifier value="stringed"></qualifier>這個有沒有都可以哎,我用的spring版本是spring4.2.9的,難道版本高了,功能也自動升級了,不是很明白:

?創建自定義的限定器(Qualifiler)(這個感覺好吊的樣子,因為看不懂,感覺像是自己創建了個自定義的注解)

?首先創建一個接口:

1 package com.springinaction.springidol; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 import org.springframework.beans.factory.annotation.Qualifier; 9 10 @Target({ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE}) 11 @Retention(RetentionPolicy.RUNTIME) 12 @Qualifier 13 public @interface StringedInstrument { 14 15 } View Code 1 package com.springinaction.springidol; 2 3 4 /** 5 * 6 * @ClassName: Guitar 7 * @Description: 樂器:吉他 8 * @author mao 9 * @date 2017年3月19日 下午8:15:44 10 * 11 */ 12 @StringedInstrument//好嘛?這應該是自定義的注解吧 13 public class Guitar implements Instrument { 14 15 public Guitar(){ 16 17 } 18 19 public void play() { 20 System.out.println("guitar guitar guitar"); 21 } 22 23 } View Code 1 @Autowired 2 //@Qualifier("guitar") 3 @StringedInstrument 4 private Instrument instrument; View Code 1 <bean class="com.springinaction.springidol.Guitar"> 2 <!-- <qualifier value="stringed"></qualifier> 這一行有沒有不影響 --> 3 </bean> 4 5 <bean id="kenny" 6 class="com.springinaction.springidol.Instrumentalist"> 7 <property name="song" value="演員——薛之謙"></property> 8 </bean> View Code 1 //測試注解@Autowired @StringedInstrument 2 @Test 3 public void testAutowired() throws Exception { 4 5 Instrumentalist kenny = (Instrumentalist) ac.getBean("kenny"); 6 kenny.perform(); 7 kenny.getInstrument().play(); 8 9 } View Code

如果有多個樂器類被@StringedInstrument標注了,還需要再進行細粒度的控制,感覺這個太麻煩!要自定義很多個限定器!

3.2.2 借助@Inject實現基于標準的自動裝配

JSR-330是一種依賴注入規范,更常見的叫法at inject

這個要用到新的jar文件,javax.inject,所以pom.xml文件中需要引入該jar依賴;

1 <!-- JSR-330的標準注解 --> 2 <dependency> 3 <groupId>javax.inject</groupId> 4 <artifactId>javax.inject</artifactId> 5 <version>1</version> 6 </dependency> View Code

這個jar內容如下,總共就這些類:

?

@Inject注解和@Autowired一樣,可以用來自動裝配屬性、方法和構造器;與@Autowired不同的是,@Inject沒有required屬性。

@Inject他也可以限定,用@Name,@Autowired用的@Qualifier:

1 @Inject 2 @Named("guitar") 3 private Instrument instrument; View Code

基本用法和@Autowired差不多,@Name和@Qualifier區別:前者是通過Bean的ID來表示可選擇的Bean,后者是幫助我們縮小匹配Bean的選擇范圍(目前沒有感覺到太大的差一性);

3.2.3 在注解注入中使用表達式

Spring3.0引入了@Value,可以裝配String類型的值和基本類型的值,例如。

@Value("Eruption")

private String song;

@Value與SpEL表達式配合,才能顯示他的魔力(第二章中的SpEL表達式);

3.3 自動檢測Bean

  <context:annotation-config/>需要顯示定義<bean>,用<context:annotation-scan>允許spring自動檢測Bean和定義Bean。為了配置Spring自動檢測,需要使用<context:conponent-scan>元素代替<context:annotation-config>元素,元素會掃描指定的包及其所有子包,并查處自動注冊的Spring Bean的類。

1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:p="http://www.springframework.org/schema/p" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 10 <context:component-scan 11 base-package="com.springinaction.springidol"> </context:component-scan> 12 </beans> View Code

3.3.1 為自動檢測標注Bean

  <context:componment-scan>查找使用構造型(stereotype)注解所標注的類:

  • @Component——通用的構造型注解,標識該類為Spring組件
  • @Constroller——標識將該類定義為SpringMVC controller
  • @Repository——標識將該類定義為數據倉庫
  • @Service——標識將該類定義為服務
1 package com.springinaction.springidol; 2 3 import org.springframework.stereotype.Component; 4 5 6 /** 7 * 8 * @ClassName: Guitar 9 * @Description: 樂器:吉他 10 * @author mao 11 * @date 2017年3月19日 下午8:15:44 12 * 13 */ 14 //自動將該類注冊為Spring Bean。Bean的ID默認無限定類名。在這種場景下,Guitar Bean的ID為guitar 15 @Component 16 public class Guitar implements Instrument { 17 18 public Guitar(){ 19 20 } 21 22 public void play() { 23 System.out.println("guitar guitar guitar"); 24 } 25 26 } View Code 1 package com.springinaction.springidol; 2 3 import javax.inject.Inject; 4 import javax.inject.Named; 5 6 import org.springframework.beans.factory.annotation.Value; 7 import org.springframework.stereotype.Component; 8 9 10 11 /** 12 * 13 * @ClassName: Instrumentalist 14 * @Description: 一個有天賦的音樂家 15 * @author mao 16 * @date 2017年3月19日 下午7:15:17 17 * 18 */ 19 //將該類注冊到Spring容器中,顯示的為其命名為eddie。即ID為eddie 20 @Component("eddie") 21 public class Instrumentalist implements Performer { 22 23 @Value("演員--薛之謙") 24 private String song; 25 26 @Inject 27 @Named("guitar") 28 private Instrument instrument; 29 30 //注入樂器 31 public void setInstrument(Instrument instrument) { 32 this.instrument = instrument; 33 } 34 public Instrument getInstrument() { 35 return instrument; 36 } 37 //注入歌曲 38 public void setSong(String song) { 39 this.song = song; 40 } 41 public String getSong() { 42 return song; 43 } 44 45 public Instrumentalist(){ 46 47 } 48 49 public void perform() throws Exception { 50 System.out.println("Playing "+song+": "); 51 } 52 53 } View Code 1 //測試注解@Component 2 @Test 3 public void testComponent() throws Exception { 4 5 Instrumentalist eddie = (Instrumentalist) ac.getBean("eddie"); 6 eddie.perform(); 7 eddie.getInstrument().play(); 8 9 } View Code

測試結果:

3.4 使用spring基于java的配置

3.4.1 創建基于Java的配置

  即使Spring的java配置可以使用XML就可以編寫大多數的Spring配置,但是我們仍然需要極少量的XML來啟用Java配置:

1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:p="http://www.springframework.org/schema/p" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 10 <context:component-scan 11 base-package="com.springinaction.springidol*"></context:component-scan> 12 13 </beans> View Code

  首先創建一個類,用@Configuration標注該類,使用它標注后,這個類就相當于<beans>容器了:

1 package com.springinaction.springidol; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 6 //在基于java的配置里使用@Configuration注解java類,就等價于XML配置中的<beans> 7 //@Configuration注解會作為一個標識告知Spring:這個類將包含一個多個SpringBean的定義。 8 //這些Bean的定義是使用@Bean注解所標注的方法。 9 @Configuration 10 public class SpingIdolConfig { 11 12 /* 13 * 它等價于使用XML所配置的<bean>元素。@Bean告知Sping這個方法返回一個對象, 14 * 該對象應該被注冊為Spring應用上下文中的一個Bean。方法名將作為該Bean的ID 15 */ 16 @Bean 17 public Performer duke(){ 18 return new Juggler(); 19 } 20 21 @Bean 22 public Performer kenny(){ 23 24 Instrumentalist kenny = new Instrumentalist(); 25 kenny.setSong("認真的雪Bean----薛之謙"); 26 kenny.setInstrument(guitar()); 27 return kenny; 28 29 } 30 31 @Bean 32 public Instrument guitar(){ 33 return new Guitar(); 34 } 35 36 } View Code

  此時Instrumentalist類是這樣的,兩個屬性的注解被注釋了:

1 package com.springinaction.springidol; 2 3 import javax.inject.Inject; 4 import javax.inject.Named; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Qualifier; 8 import org.springframework.beans.factory.annotation.Value; 9 import org.springframework.stereotype.Component; 10 11 12 13 /** 14 * 15 * @ClassName: Instrumentalist 16 * @Description: 一個有天賦的音樂家 17 * @author mao 18 * @date 2017年3月19日 下午7:15:17 19 * 20 */ 21 //將該類注冊到Spring容器中,顯示的為其命名為eddie。即ID為eddie 22 23 public class Instrumentalist implements Performer { 24 25 // @Value("演員---薛之謙") 26 private String song; 27 28 // @Autowired 29 // @Qualifier("saxophone") 30 private Instrument instrument; 31 32 //注入樂器 33 public void setInstrument(Instrument instrument) { 34 this.instrument = instrument; 35 } 36 public Instrument getInstrument() { 37 return instrument; 38 } 39 //注入歌曲 40 public void setSong(String song) { 41 this.song = song; 42 } 43 public String getSong() { 44 return song; 45 } 46 47 public Instrumentalist(){ 48 49 } 50 51 public void perform() throws Exception { 52 System.out.println("Playing "+song+": "); 53 } 54 55 } View Code

  測試代碼:

1 //測試基于java的配置 2 @Test 3 public void testJava() throws Exception { 4 5 Instrumentalist eddie = (Instrumentalist) ac.getBean("kenny"); 6 eddie.perform(); 7 eddie.getInstrument().play(); 8 9 } View Code

  結果:

  這個基于java的注解,若是將上述的兩個注釋的注解解封:

1 package com.springinaction.springidol; 2 3 import javax.inject.Inject; 4 import javax.inject.Named; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.beans.factory.annotation.Qualifier; 8 import org.springframework.beans.factory.annotation.Value; 9 import org.springframework.stereotype.Component; 10 11 12 13 /** 14 * 15 * @ClassName: Instrumentalist 16 * @Description: 一個有天賦的音樂家 17 * @author mao 18 * @date 2017年3月19日 下午7:15:17 19 * 20 */ 21 //將該類注冊到Spring容器中,顯示的為其命名為eddie。即ID為eddie 22 23 public class Instrumentalist implements Performer { 24 25 @Value("演員---薛之謙") 26 private String song; 27 28 @Autowired 29 @Qualifier("saxophone") 30 private Instrument instrument; 31 32 //注入樂器 33 public void setInstrument(Instrument instrument) { 34 this.instrument = instrument; 35 } 36 public Instrument getInstrument() { 37 return instrument; 38 } 39 //注入歌曲 40 public void setSong(String song) { 41 this.song = song; 42 } 43 public String getSong() { 44 return song; 45 } 46 47 public Instrumentalist(){ 48 49 } 50 51 public void perform() throws Exception { 52 System.out.println("Playing "+song+": "); 53 } 54 55 } View Code

  結果就是:

  這個感覺像是就近原則啊(xml的注解在屬性上方),要么是先是執行了基于java的配置,后又執行了基于xml的配置,xml的配置覆蓋了前者的結果。

?源碼下載地址

轉載于:https://www.cnblogs.com/huaxueyihao/p/6594501.html

總結

以上是生活随笔為你收集整理的第三章 最小化SpringXml 配置的全部內容,希望文章能夠幫你解決所遇到的問題。

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