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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

srping基础——DI(三)

發布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 srping基础——DI(三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、依賴和依賴注入

  傳統應用程序設計中所說的依賴一般指的是“類與類之間的關系”,那么首先讓我們復習一下類之間的關系:

  泛化:表示類與類之間的繼承關系,表示接口與接口之間的繼承關系;

  

  實現:表示類對接口的實現;

  

  依賴:當類與類之間有使用關系時就屬于依賴關系,不同于關聯關系,依賴不具有“擁有關系”,而是一種相識關系,只在某個特定的地方才有關系。

  

  關聯:表示接口與接口或類與類之間的依賴關系,表現為“擁有關系”;具體代碼可以用實例變量來表示。

  

  組合:屬于關聯的特殊情況,體現了部分整體的關系,是一種“強擁有關系”;整體與部分擁有相同的生命周期,是一種強關聯;

  

  聚合:屬于關聯的特殊情況,也體現了部分整體的關系,是一種“弱擁有關系”;整體和部分可以有不一樣的生命周期。是一種弱關聯;

  

  它們關系的強弱順序:泛化= 實現> 組合> 聚合> 關聯> 依賴?

  spring IoC容器依賴有兩層含義:bean依賴容器容器注入bean的依賴資源

  • bean依賴容器:這里的依賴是指容器負責創建bean,并管理bean的生命周期,正式由于容器來控制創建bean并注入依賴,也就是控制值被反轉了,這也正式IoC名字的由來,此處的依賴指的是bean和容器之間的依賴關系。
  • 容器注入bean的依賴資源:依賴資源可以是bean、外部文件、常量數據等,在Java中都反應為對象,并且有容器負責組裝bean之間的依賴關系,此處的依賴指的是bean之間的關系可以認為是傳統類與類之間的關聯、組合、聚合關系。

2、為什么要依賴注入

  • 動態替換bean依賴對象,程序更靈活:替換bean對象無需更改源文件,直接修改配置文件即可。
  • 更好實踐面向接口編程,代碼更清晰:在bean中只需指定依賴對象的接口,接口定義依賴對象完成的功能,通過容器注入依賴實現。
  • 更好實踐優先使用組合,而不是繼承:因為IoC容器采用注入依賴,也就是組合對象,從而更好的實現對象的組合。 
  • 增加bean的復用性:依賴于對象組合,bean可復用且復用更簡單
  • 降低bean之間的耦合:由于我們完全面向接口編程,在代碼中沒有直接引用bean依賴實現,全部引用接口,而且不會顯示創建依賴對象代碼。
  • 代碼結構更清晰:要應用依賴注入,代碼結構要按照規約方式進行書寫,從而更好的應用一些最佳實踐,因此代碼結構更清晰。

  如何設計好類結構才是關鍵,依賴注入只是裝配對象的一種手段。上一篇我們已經了解了bean依賴容器,spring IoC容器注入依賴資源主要有以下三種形式:

  構造器注入:就是容器實例化bean時注入那些依賴,通過在bean定義中指定構造器參數注入依賴,包括實例工廠方法參數注入依賴。

  setter注入:通過setter方法注入依賴。

  方法注入:通過配置方式替換掉bean方法,也就是通過配置改變bean方法功能。

3、依賴注入具體配置

  3.1 構造器注入:

    3.1.1?使用構造器注入通過配置構造器參數實現,構造器參數就是依賴。除了構造器方式還有實例工廠,靜態工廠可以進行構造器注入。

    

    構造器注入可以根據參數的索引注入,參數的類型注入或參數名注入(參數名注入有限制:編譯程序時打開調試模式或在構造器上使用@ConstructorProperties注解指定參數名)

1 public class HelloImpl3 implements HelloApi { 2   private String message; 3    private int index; 4    //@java.beans.ConstructorProperties({"message", "index"}) 5   public HelloImpl3(String message, int index) { 6     this.message = message; 7     this.index = index; 8   } 9   @Override 10   public void sayHello() { 11   System.out.println(index + ":" + message); 12 } 1 <!-- 通過構造器參數索引方式依賴注入 --> 2 <bean id="byIndex" class="cn.javass.spring.chapter3.HelloImpl3"> 3   <constructor-arg index="0" value="Hello World!"/> 4   <constructor-arg index="1" value="1"/> 5 </bean> 6 <!-- 通過構造器參數類型方式依賴注入 --> 7 <bean id="byType" class="cn.javass.spring.chapter3.HelloImpl3"> 8 <constructor-arg type="java.lang.String" value="Hello World!"/> 9 <constructor-arg type="int" value="2"/> 10 </bean> 11 <!-- 通過構造器參數名稱方式依賴注入 --> 12 <bean id="byName" class="cn.javass.spring.chapter3.HelloImpl3"> 13 <constructor-arg name="message" value="Hello World!"/> 14 <constructor-arg name="index" value="3"/> 15 </bean> 1 @Test 2 public void testConstructorDependencyInjectTest() { 3   BeanFactory beanFactory = new ClassPathXmlApplicationContext("chapter3/constructorDependencyInject.xml"); 4   //獲取根據參數索引依賴注入的Bean 5   HelloApi byIndex = beanFactory.getBean("byIndex", HelloApi.class); 6   byIndex.sayHello(); 7   //獲取根據參數類型依賴注入的Bean 8   HelloApi byType = beanFactory.getBean("byType", HelloApi.class); 9   byType.sayHello(); 10   //獲取根據參數名字依賴注入的Bean 11   HelloApi byName = beanFactory.getBean("byName", HelloApi.class); 12   byName.sayHello(); 13 }

?    3.1.2?靜態工廠方法注入和實例工廠方法注入

1 <!--靜態工廠方法--> 2 <bean id="byIndex" class="cn.javass.spring.chapter3.DependencyInjectByStaticFactory" factory-method="newInstance"> 3   <constructor-arg index="0" value="Hello World!"/> 4   <constructor-arg index="1" value="1"/> 5 </bean> 6 <bean id="byType" class="cn.javass.spring.chapter3.DependencyInjectByStaticFactory" factory-method="newInstance"> 7   <constructor-arg type="java.lang.String" value="Hello World!"/> 8   <constructor-arg type="int" value="2"/> 9 </bean> 10 <bean id="byName" class="cn.javass.spring.chapter3.DependencyInjectByStaticFactory" factory-method="newInstance"> 11   <constructor-arg name="message" value="Hello World!"/> 12   <constructor-arg name="index" value="3"/> 13 </bean> 24 <!--實例工廠方法--> 25 <bean id="instanceFactory" class="cn.javass.spring.chapter3.DependencyInjectByInstanceFactory"/> 26 <bean id="byIndex" factory-bean="instanceFactory" factory-method="newInstance"> 27 <constructor-arg index="0" value="Hello World!"/> 28   <constructor-arg index="1" value="1"/> 29 </bean> 30 <bean id="byType" factory-bean="instanceFactory" factory-method="newInstance"> 31   <constructor-arg type="java.lang.String" value="Hello World!"/> 32   <constructor-arg type="int" value="2"/> 33 </bean> 34 <bean id="byName" factory-bean="instanceFactory" factory-method="newInstance"> 35   <constructor-arg name="message" value="Hello World!"/> 36   <constructor-arg name="index" value="3"/> 37 </bean> 1 //靜態工廠類 2 package cn.javass.spring.chapter3; 3 import cn.javass.spring.chapter2.helloworld.HelloApi; 4 public class DependencyInjectByStaticFactory { 5   public static HelloApi newInstance(String message, int index) { 6   return new HelloImpl3(message, index); 7   } 8 } 9 //實例工廠類 10 package cn.javass.spring.chapter3; 11 import cn.javass.spring.chapter2.helloworld.HelloApi; 12 public class DependencyInjectByInstanceFactory { 13    public HelloApi newInstance(String message, int index) { 14   return new HelloImpl3(message, index); 15   } 16 }

?  因為參數名需做額外配置,因此不建議使用根據參數名進行構造器注入

  3.2 setter注入

  setter注入,是通過構造器、靜態工廠、實例工廠實例化好bean中,再調用bean類的setter方法注入依賴。

  

1 <!-- 通過setter方式進行依賴注入 --> 2 <bean id="bean" class="cn.javass.spring.chapter3.HelloImpl4"> 3   <property name="message" value="Hello World!"/> 4     <property name="index"> 5     <value>1</value> 6   </property> 7 </bean> 1 package cn.javass.spring.chapter3; 2 import cn.javass.spring.chapter2.helloworld.HelloApi; 3 public class HelloImpl4 implements HelloApi { 4   private String message; 5   private int index; 6   //setter方法 7   public void setMessage(String message) { 8   this.message = message; 9   } 10   public void setIndex(int index) { 11   this.index = index; 12   } 13   @Override 14   public void sayHello() { 15   System.out.println(index + ":" + message); 16   } 17 } 18 19 @Test 20 public void testSetterDependencyInject() { 21   BeanFactory beanFactory = new ClassPathXmlApplicationContext("chapter3/setterDependencyInject.xml"); 22   HelloApi bean = beanFactory.getBean("bean", HelloApi.class); 23   bean.sayHello(); 24 }

  JavaBean本質就是一個pojo,具體有如下限制:

    該類必須有公共的無慘構造器

    屬性為private訪問級別

    屬性必要時通過一組setter和getter方法來訪問

  3.3 常量注入

    注入常量是依賴注入中最簡單的,配置方式如下:

1 <property name="message" value="Hello World!"/> 2 3 <property name="index"><value>1</value></property>

    以上兩種方式都可以,從配置來看第一種更簡潔,此處的value中指定的全是字符串,由spring容器將此字符串轉換成屬性所需的類型,如果轉換出錯則拋出相應的異常。spring容器目前能對各種基本類型把配置的字符串參數轉換為所需的類型。

1 //測試類 2 public class BooleanTestBean { 3   private boolean success; 4   public void setSuccess(boolean success) { 5   this.success = success; 6   } 7   public boolean isSuccess() { 8   return success; 9   } 10 } 1 <!-- boolean參數值可以用on/off --> 2 <bean id="bean2" class="cn.javass.spring.chapter3.bean.BooleanTestBean"> 3 <property name="success" value="on"/> 4 </bean> 5 <!-- boolean參數值可以用yes/no --> 6 <bean id="bean3" class="cn.javass.spring.chapter3.bean.BooleanTestBean"> 7 <property name="success" value="yes"/> 8 </bean> 9 <!-- boolean參數值可以用1/0 --> 10 <bean id="bean4" class="cn.javass.spring.chapter3.bean.BooleanTestBean"> 11 <property name="success" value="1"/> 12 </bean>

  3.4 注入集合、數組和字典

    spring IoC容器不僅能注入簡單的數據類型,還能注入集合(Collection、Set、List)類型、數組類型、字典數據類型、Properties類型。

    3.4.1?注入集合類型:

  • List類型:需要使用list標簽注入,其具體配置如下:

  

1 <bean id="listBean" class="cn.javass.spring.chapter3.bean.ListTestBean"> 2 <property name="values"> 3   <list> 4     <value>1</value> 5     <value>2</value> 6     <value>3</value> 7   </list> 8 </property> 9 </bean> 1 package cn.javass.spring.chapter3.bean; 2 import java.util.List; 3 public class ListTestBean { 4   private List<String> values; 5   public List<String> getValues() { 6     return values; 7   } 8   public void setValues(List<String> values) { 9     this.values = values; 10   } 11 } 12 @Test 13 public void testListInject() { 14 BeanFactory beanFactory = new ClassPathXmlApplicationContext("chapter3/listInject.xml"); 15   ListTestBean listBean = beanFactory.getBean("listBean", ListTestBean.class); 16   System.out.println(listBean.getValues().size()); 17   Assert.assertEquals(3, listBean.getValues().size()); 18 }
  • set類型:需要使用set標簽來配置注入,其配置參數含義與list相同
1 <bean id="setBean" class="cn.javass.spring.chapter3.bean.SetTestBean"> 2   <property name="values"> 3     <set> 4       <value>1</value> 5       <value>2</value> 6       <value>3</value> 7     </set> 8   </property> 9 </bean> 1 package cn.javass.spring.chapter3.bean; 2 import java.util.Set; 3 public class SetTestBean { 4   private Set<String> values; 5   public void setValues(Set<String> values) { 6     this.values = values; 7   } 8   public Set<String> getValues() { 9     return values; 10   } 11 }
  • Collection類型:由于Collection類型是List和Set類型的基類型,所以使用list和set標簽都可以進行注入,配置方式和以上配置方式相同。

    3.4.2 注入數組類型

      需要使用array標簽來配置注入,其中標簽屬性“value-type”和“merge”與list標簽含義完全相同。具體配置如下:

      

    3.4.3 注入字典類型:

      字典類型是包含鍵值對數據的數據結構,需要使用map、entry標簽來配置注入,其屬性key-type和value-type分別指定鍵值數據類型,其含義同list標簽相同。使用key、value字標簽分別指定鍵值數據。具體配置如下:

      

    3.4.4 Properties注入:

      spring能注入java.util.Properties類型數據,需要使用props標簽來配置注入,鍵值類型必須是String,不能變。字標簽<prop key=“鍵”>值<prop>來指定鍵值對,具體配置如下:

      

    

?

?

 

?

轉載于:https://www.cnblogs.com/ouhouki/p/9692701.html

總結

以上是生活随笔為你收集整理的srping基础——DI(三)的全部內容,希望文章能夠幫你解決所遇到的問題。

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