Spring的依賴注入的方式
Spring依賴注入的方式
建構函式注入
在bean標籤的內部使用constructor-arg標籤就可以進行建構函式注入了。
constructor-arg標籤的屬性:
- type:用於指定要注入的資料的資料型別,該資料型別也是建構函式中某個或某些引數的型別
- index:用於指定要注入的資料給建構函式中指定索引位置的引數賦值,索引的位置從0開始
- name:用於給指定建構函式中指定名稱的引數賦值
- value:用於提供基本型別和String型別的資料
- ref:用於指定其他的bean型別資料,就是在IOC容器中出現過的bean物件
bean.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/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountService" class="com.sks.service.imp.AccountServiceImpl">
<constructor-arg type="java.lang.String" value="張三"/>
<constructor-arg index="1" value="20"/>
<constructor-arg name="birthday" ref="birthday"/>
</bean>
<bean id="birthday" class="java.util.Date"/>
</beans>
AccountServiceImpl 類
public class AccountServiceImpl implements AccountService {
private String name;
private Integer age;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "AccountServiceImpl{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
'}';
}
public AccountServiceImpl(String name, Integer age, Date birthday) {
System.out.println("含參的構造方法被呼叫了");
this.name = name;
this.age = age;
this.birthday = birthday;
}
public AccountServiceImpl() {
System.out.println("構造方法呼叫");
}
@Override
public int addMoney(int money) {
System.out.println("向賬戶中加錢:" + money);
return 0;
}
@Override
public void saveAccount(Account account) {
System.out.println("saveAccount方法執行了");
}
}
測試
/**
* 測試建構函式注入
*/
@Test
public void test8() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");;
AccountService accountService = (AccountService) applicationContext.getBean("accountService");
System.out.println(accountService.toString());
}
執行測試以後,可以在控制檯看到以下內容:
優點:在獲取bean物件時,注入資料是必須的操作,否則物件無法建立成功。
缺點:改變了bean物件的例項化方式,使我們在建立物件時,如果用不到這些資料也必須提供。
setter方法注入
在bean標籤內部使用property標籤進行配置。
property標籤的屬性:
- name:用於指定注入時所呼叫的set方法名稱
- value:用於提供基本型別和String型別的資料
- ref:用於指定其他的bean型別資料
這裡面我們注入了基本型別、包裝型別、日期型別資料。
AccountServiceImpl 類
public class AccountServiceImpl implements AccountService {
private String name;
private Integer age;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("給name設定值");
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
System.out.println("給age設定值");
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
System.out.println("給birthday設定值");
this.birthday = birthday;
}
@Override
public String toString() {
return "AccountServiceImpl{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
'}';
}
public AccountServiceImpl(String name, Integer age, Date birthday) {
System.out.println("含參的構造方法被呼叫了");
this.name = name;
this.age = age;
this.birthday = birthday;
}
public AccountServiceImpl() {
System.out.println("構造方法呼叫");
}
@Override
public int addMoney(int money) {
System.out.println("向賬戶中加錢:" + money);
return 0;
}
@Override
public void saveAccount(Account account) {
System.out.println("saveAccount方法執行了");
}
}
bean.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/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountService" class="com.sks.service.imp.AccountServiceImpl">
<!--注入基本型別、包裝型別、日期型別資料-->
<property name="age" value="22"/>
<property name="name" value="李四"/>
<property name="birthday" ref="birthday"/>
</bean>
<bean id="birthday" class="java.util.Date"/>
</beans>
測試
/**
* 測試setter方法注入
*/
@Test
public void test9() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");;
AccountService accountService = (AccountService) applicationContext.getBean("accountService");
System.out.println(accountService.toString());
}
執行測試以後,可以在控制檯看到以下內容:
優勢:建立物件時沒有明確的限制,可以直接使用預設建構函式。
缺點:如果又某個成員必須有值,則獲取物件有可能是set方法沒有執行。
對集合型別資料進行注入
AccountService2Impl 類
public class AccountService2Impl implements AccountService2 {
private String[] myStrs;
private List<String> myList;
private Set<String> mySet;
private Map<String, String> myMap;
private Properties myProps;
public String[] getMyStrs() {
return myStrs;
}
public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
public List<String> getMyList() {
return myList;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public Set<String> getMySet() {
return mySet;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public Map<String, String> getMyMap() {
return myMap;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public Properties getMyProps() {
return myProps;
}
public void setMyProps(Properties myProps) {
this.myProps = myProps;
}
@Override
public String toString() {
return "AccountService2Impl{" +
"myStrs=" + Arrays.toString(myStrs) +
", myList=" + myList +
", mySet=" + mySet +
", myMap=" + myMap +
", myProps=" + myProps +
'}';
}
}
bean.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/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountService2" class="com.sks.service.imp.AccountService2Impl">
<property name="myStrs">
<array>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</array>
</property>
<property name="myList">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="mySet">
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
</property>
<property name="myProps">
<props>
<prop key="name">柯森</prop>
<prop key="age">23</prop>
</props>
</property>
<property name="myMap">
<map>
<entry key="key1" value="value1"/>
<entry key="key2" value="value2"/>
<entry key="key3">
<value>value3</value>
</entry>
</map>
</property>
</bean>
</beans>
測試
/**
* 測試注入複雜型別/集合資料
*/
@Test
public void test10() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");
AccountService2 accountService2 = (AccountService2) applicationContext.getBean("accountService2");
System.out.println(accountService2.toString());
}
執行測試以後,可以看到在控制檯列印輸出了以下內容:
這說明我們注入集合型別資料成功了。
註解注入
用於注入資料的註解
註解 | 作用 |
---|---|
@Autowired | 按照型別注入,如果又多個型別相同的再按名稱 |
@Qualifier | 在按照類中注入的基礎之上再按照名稱注入;屬性:value,用於指定注入bean的id |
@Resource | 直接按照bean的id注入,可以獨立使用 |
@Value | 注入基本型別的資料,不能注入集合 |
bean.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--建立bean時要掃描的包-->
<context:component-scan base-package="com.sks"/>
</beans>
AccountService4Impl 類
@Component
public class AccountService4Impl implements AccountService3 {
@Autowired
private AccountDao accountDao;
@Override
public void addMoney(int money) {
System.out.println("向賬戶中加錢....AccountService3Impl");
}
}
假設此時只有一個AccountDao的實現類,並且這個類也加上了@Repository註解,那麼我們這樣注入是可以成功的,但是如果容器中存在多個AccountDao的實現類,此時僅僅使用AccountDao是不能完成資料注入的,需要配合@Qualifier註解使用注入資料。
假設現有如下兩個實現類,那我們應該怎麼寫才能成功注入資料?
@Component
public class AccountService4Impl implements AccountService3 {
//錯誤寫法,預設會去容器中查詢名稱為accountDao的bean
//@Autowired
//private AccountDao accountDao;
//正確寫法
//@Autowired
//private AccountDao accountDao1
//正確寫法
//@Autowired
//private AccountDao accountDao1;
//正確寫法
@Autowired
@Qualifier("accountDao1")
private AccountDao accountDao;
@Override
public void addMoney(int money) {
System.out.println("向賬戶中加錢....AccountService3Impl");
}
}
測試
@Test
public void test2() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");
AccountService4Impl accountService4 = (AccountService4Impl) applicationContext.getBean("accountService4Impl");
System.out.println("accountService4:" + accountService4);
}
@Value註解的基本使用
在使用@Value注入基本型別和String型別的資料時使用"#“號;使用@Value讀取配置檔案的值時需要使用”$"符號,同時使用@PropertySource註解指定配置檔案的位置。
@Component
@PropertySource("classpath:db.properties")
public class AccountService4Impl implements AccountService3 {
@Autowired
@Qualifier("accountDao1")
private AccountDao accountDao;
//使用SPEL表示式只注入值
@Value("#{19 - 9}")
private int age;
@Value("zhangsan")
private String name;
//讀取作業系統的名稱
@Value("#{systemProperties['os.name']}")
private String osname;
//讀取資料庫配置檔案中的值
@Value("${password}")
private String password;
@Override
public void addMoney(int money) {
System.out.println("向賬戶中加錢....AccountService3Impl");
}
}
測試
@Test
public void test2() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");
AccountService4Impl accountService4 = (AccountService4Impl) applicationContext.getBean("accountService4Impl");
System.out.println("accountService4:" + accountService4 + " " + accountService4.getName() + " " + accountService4.getAge());
}
斷點除錯可以看到如下結果,說明我們使用@Value注入資料成功。
相關文章
- Spring的三種依賴注入的方式Spring依賴注入
- spring常用的三種依賴注入方式Spring依賴注入
- spring 的依賴注入Spring依賴注入
- Spring 依賴注入的理解Spring依賴注入
- Spring依賴注入Spring依賴注入
- Spring依賴注入---Spring依賴注入
- spring 依賴注入的學習Spring依賴注入
- Spring IOC——依賴注入Spring依賴注入
- Spring 依賴注入 DISpring依賴注入
- Spring依賴注入的兩種方式(根據例項詳解)Spring依賴注入
- Spring系列.依賴注入配置Spring依賴注入
- Spring.Net 依賴注入Spring依賴注入
- 大白話spring依賴注入Spring依賴注入
- 2.3 Spring的核心機制:依賴注入Spring依賴注入
- 依賴注入?依賴注入是如何實現解耦的?依賴注入解耦
- Spring6框架中依賴注入的多種方式(推薦構造器注入)Spring框架依賴注入
- ASP.NET Core中的依賴注入(2):依賴注入(DI)ASP.NET依賴注入
- spring框架學習 依賴注入Spring框架依賴注入
- Spring依賴注入原理學習Spring依賴注入
- Spring學習(三)依賴注入Spring依賴注入
- Spring的核心機制依賴注入簡介Spring依賴注入
- 從Hessian RPC 註解方式看Spring依賴注入RPCSpring依賴注入
- JavaScript裡的依賴注入JavaScript依賴注入
- 在WPF中使用依賴注入的方式建立檢視依賴注入
- 如何用最簡單的方式解釋依賴注入?依賴注入是如何實現解耦的?(通俗易懂)依賴注入解耦
- 死磕Spring原始碼-依賴注入Spring原始碼依賴注入
- Spring原始碼解析——依賴注入(二)Spring原始碼依賴注入
- Spring 控制反轉和依賴注入Spring依賴注入
- Spring原始碼系列:依賴注入-引言Spring原始碼依賴注入
- Spring系列第八講 依賴注入之手動注入Spring依賴注入
- Spring原始碼系列:依賴注入(三)-屬性注入Spring原始碼依賴注入
- angular依賴注入Angular依賴注入
- XUnit 依賴注入依賴注入
- Struts 依賴注入依賴注入
- SpringDI四種依賴注入方式詳解Spring依賴注入
- 類的反射和依賴注入反射依賴注入
- [譯]javascript中的依賴注入JavaScript依賴注入
- 依賴倒置(DIP)與依賴注入(DI)依賴注入