javascript
Spring依赖注入和简单demo
參考:
1. 定義
1.1 概念
依賴注入 Dependency Injection
依賴:bean對象的創(chuàng)建依賴于容器
注入:bean對象中的所有屬性,由容器來注入
1.2 分類
Spring依賴注入( Dependency Injection)有兩大方式:1. 構(gòu)造器注入(Constructor-based Dependency Injection)2. Set方法注入(Setter-based Dependency Injection)。此外還有c/p命名空間注入,但其本質(zhì)還是這兩大方式。需要區(qū)分的是,一個是在構(gòu)造對象的時候進(jìn)行注入,一個是在構(gòu)造完對象后使用set方法進(jìn)行注入。
1.3 注意
2. Set方法注入
2.1 pojo
現(xiàn)在假如有一個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;// 每個屬性都有相應(yīng)的get/set方法... }2.2 XML配置文件
那么相對應(yīng)的xml配置文件應(yīng)該是這樣的:
<?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. 數(shù)組注入,array --><property name="books" ><array><!-- 如果是value="",需要雙引號;如果是<value>xxx</value>,中間不需要雙引號 --><value>指環(huán)王1</value><value>指環(huán)王2</value><value>"指環(huán)王3"</value></array></property><!-- 4. List注入,list --><property name="hobbies" ><list><value>健身</value><value>學(xué)習(xí)</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",然后將第一個字符小寫后的結(jié)果。比如我特意把name的第一個字母設(shè)置成小寫,Age的第一個字母設(shè)置成大寫,他們的set方法都是setName()和setAge(),根據(jù)上面的注意點,在xml中寫屬性的name時,都得統(tǒng)一使用小寫。
3. 構(gòu)造器注入(四種方式)
3.1 根據(jù)引用
這里的引用是指除了Java基本類型之外的類型,并且已經(jīng)在.xml文件中注冊過的bean。
ThingOne
package x.y;public class ThingOne {public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {// ...} }這里假設(shè)ThingTwo和ThingThree沒有繼承上的相關(guān)性,因此沒有ambiguity,無需顯式地表明構(gòu)造器參數(shù)下標(biāo)或類型。
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 根據(jù)類型(不建議使用)
前面的例子使用了reference,需要清楚的知道引用的是什么類型。在使用基本類型的時候,需要顯式表明參數(shù)的類型,避免ambiguity。需要注意的是,類型并不需要按構(gòu)造器中聲明的順序編寫。然而根據(jù)類型來注入還是會引起ambiguity,比如當(dāng)構(gòu)造器有多個相同類型的參數(shù)時,將會有ambiguity。應(yīng)當(dāng)使用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 根據(jù)參數(shù)名(最好用,最直接)
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,則是構(gòu)造器參數(shù)的名稱。
請記住,要使其開箱即用,您的代碼必須在啟用調(diào)試標(biāo)志的情況下編譯,以便Spring可以從構(gòu)造函數(shù)中查找參數(shù)名。如果不能或不想使用調(diào)試標(biāo)志編譯代碼,可以使用@ConstructorProperties JDK注釋顯式地命名構(gòu)造函數(shù)參數(shù)。樣例類應(yīng)該如下所示:
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 根據(jù)下標(biāo)
XML
<bean id="exampleBean" class="examples.ExampleBean"><constructor-arg index="0" value="7500000"/><constructor-arg index="1" value="42"/> </bean>使用下標(biāo)可以很好地解決,構(gòu)造器有兩個同樣類型的參數(shù)的情況。
注意:根據(jù)下標(biāo)注入,下標(biāo)從0開始。使用上面的方式配置,若賦值的類型與參數(shù)的類型不一致,將會在容器初始化bean的時候拋出異常。如果bean存在多個參數(shù)數(shù)量一樣的構(gòu)造器,Spring容器會自動找到類型匹配的那個進(jìn)行調(diào)用。假如兩個構(gòu)造器都滿足傳入的value的類型,換言之,若存在多個構(gòu)造器匹配bean的定義,Spring容器總是使用最后一個滿足條件的構(gòu)造器。
4. p/c命名空間
p-namespace里的p對應(yīng)的是properties,也對應(yīng)著Set方法注入
c-namespace里的c對應(yīng)的是constructor,也對應(yīng)著構(gòu)造器注入
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
不能直接用,需要導(dǎo)入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
不能直接用,需要導(dǎo)入xml約束:
xmlns:c="http://www.springframework.org/schema/c"
User
// 需要無參構(gòu)造 public User() { }// 需要有參構(gòu)造 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" />總結(jié)
以上是生活随笔為你收集整理的Spring依赖注入和简单demo的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何让我们的人生,拥有更多的可能性?
- 下一篇: 【SpringCloud】Gateway