javascript
Spring依赖注入和简单demo
參考:
1. 定義
1.1 概念
依賴注入 Dependency Injection
依賴:bean對象的創建依賴于容器
注入:bean對象中的所有屬性,由容器來注入
1.2 分類
Spring依賴注入( Dependency Injection)有兩大方式:1. 構造器注入(Constructor-based Dependency Injection)2. Set方法注入(Setter-based Dependency Injection)。此外還有c/p命名空間注入,但其本質還是這兩大方式。需要區分的是,一個是在構造對象的時候進行注入,一個是在構造完對象后使用set方法進行注入。
1.3 注意
2. Set方法注入
2.1 pojo
現在假如有一個Student類:
public class Student {private String name;private String Age;private Address address;private String[] books;private List<String> hobbies;private Map<String, String> cards;private Set<String> games;private String wife;private Properties info;// 每個屬性都有相應的get/set方法... }2.2 XML配置文件
那么相對應的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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="address" class="pojo.Address"/><bean id="student" class="pojo.Student"><!-- 1. 普通值注入,value --><property name="name" value="Xiaoming" /><!-- 注意這里'age'是小寫 --><property name="age" value="15" /><!-- 2. Bean注入,ref --><property name="address" ref="address" /><!-- 3. 數組注入,array --><property name="books" ><array><!-- 如果是value="",需要雙引號;如果是<value>xxx</value>,中間不需要雙引號 --><value>指環王1</value><value>指環王2</value><value>"指環王3"</value></array></property><!-- 4. List注入,list --><property name="hobbies" ><list><value>健身</value><value>學習</value></list></property><!-- 5. Map注入,map --><property name="cards" ><map><entry key="id" value="123" /><entry key="studentid" value="321" /></map></property><!-- 6. Set注入,set --><property name="games"><set><value>CF</value><value>csgo</value></set></property><!-- 7. null注入 --><property name="wife"><null/></property><!-- 8. Properties注入 --><property name="info"><props><prop key="age">12</prop><prop key="sex">Male</prop></props></property></bean> </beans>2.3 注意點
property的name屬性,填寫的不是屬性的名稱,而是set方法去除"set",然后將第一個字符小寫后的結果。比如我特意把name的第一個字母設置成小寫,Age的第一個字母設置成大寫,他們的set方法都是setName()和setAge(),根據上面的注意點,在xml中寫屬性的name時,都得統一使用小寫。
3. 構造器注入(四種方式)
3.1 根據引用
這里的引用是指除了Java基本類型之外的類型,并且已經在.xml文件中注冊過的bean。
ThingOne
package x.y;public class ThingOne {public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {// ...} }這里假設ThingTwo和ThingThree沒有繼承上的相關性,因此沒有ambiguity,無需顯式地表明構造器參數下標或類型。
XML
<beans><bean id="beanOne" class="x.y.ThingOne"><constructor-arg ref="beanTwo"/><constructor-arg ref="beanThree"/></bean><bean id="beanTwo" class="x.y.ThingTwo"/><bean id="beanThree" class="x.y.ThingThree"/> </beans>3.2 根據類型(不建議使用)
前面的例子使用了reference,需要清楚的知道引用的是什么類型。在使用基本類型的時候,需要顯式表明參數的類型,避免ambiguity。需要注意的是,類型并不需要按構造器中聲明的順序編寫。然而根據類型來注入還是會引起ambiguity,比如當構造器有多個相同類型的參數時,將會有ambiguity。應當使用name或index。
ExampleBean
package examples;public class ExampleBean {// Number of years to calculate the Ultimate Answerprivate final int years;// The Answer to Life, the Universe, and Everythingprivate final String ultimateAnswer;public ExampleBean(int years, String ultimateAnswer) {this.years = years;this.ultimateAnswer = ultimateAnswer;} }XML
<bean id="exampleBean" class="examples.ExampleBean"><constructor-arg type="int" value="7500000"/><constructor-arg type="java.lang.String" value="42"/> </bean>3.3 根據參數名(最好用,最直接)
XML
<bean id="exampleBean" class="examples.ExampleBean"><constructor-arg name="years" value="7500000"/><constructor-arg name="ultimateAnswer" value="42"/> </bean>有人看完之后,可能會覺得這里的配置和set注入時的配置幾乎一樣,除了一個使用property,一個使用constructor-arg。確實,寫法上一樣,但是表示的含義卻完全不同。property的name屬性,是通過set()方法的名稱得來;而constructor-arg的name,則是構造器參數的名稱。
請記住,要使其開箱即用,您的代碼必須在啟用調試標志的情況下編譯,以便Spring可以從構造函數中查找參數名。如果不能或不想使用調試標志編譯代碼,可以使用@ConstructorProperties JDK注釋顯式地命名構造函數參數。樣例類應該如下所示:
ExampleBean
package examples;public class ExampleBean {// Fields omitted@ConstructorProperties({"years", "ultimateAnswer"})public ExampleBean(int years, String ultimateAnswer) {this.years = years;this.ultimateAnswer = ultimateAnswer;} }3.4 根據下標
XML
<bean id="exampleBean" class="examples.ExampleBean"><constructor-arg index="0" value="7500000"/><constructor-arg index="1" value="42"/> </bean>使用下標可以很好地解決,構造器有兩個同樣類型的參數的情況。
注意:根據下標注入,下標從0開始。使用上面的方式配置,若賦值的類型與參數的類型不一致,將會在容器初始化bean的時候拋出異常。如果bean存在多個參數數量一樣的構造器,Spring容器會自動找到類型匹配的那個進行調用。假如兩個構造器都滿足傳入的value的類型,換言之,若存在多個構造器匹配bean的定義,Spring容器總是使用最后一個滿足條件的構造器。
4. p/c命名空間
p-namespace里的p對應的是properties,也對應著Set方法注入
c-namespace里的c對應的是constructor,也對應著構造器注入
p和c的命名空間注入簡而言之就是在tag里直接注入屬性(properties),說到底都是為了簡化代碼。
“The p-namespace lets you use the bean element’s attributes (instead of nested elements) to describe your property values collaborating beans, or both.”
4.1 p-namespace
不能直接用,需要導入xml約束:
xmlns:p="http://www.springframework.org/schema/p"
User
public class User {private String name;private int age;private Address address;// getters and setters:// ... }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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="address" class="pojo.Address"/><bean id="user" class="pojo.User"p:name="Xiaoming"p:age="18"p:address-ref="address"/></beans>4.2 c-namespace
不能直接用,需要導入xml約束:
xmlns:c="http://www.springframework.org/schema/c"
User
// 需要無參構造 public User() { }// 需要有參構造 public User(String name, int age, Address address) {this.name = name;this.age = age;this.address = address; }XML
<bean id="user2" class="pojo.User"c:name="Hello"c:age="28"c:address-ref="address" />總結
以上是生活随笔為你收集整理的Spring依赖注入和简单demo的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何让我们的人生,拥有更多的可能性?
- 下一篇: 圆通梦碎高端快递:承诺达疑似解散,员工大