戴着假發的程序員 出品
[查看視頻講解]
spring可以幫我們的bean注入屬性。比如給accountServer注入accountDAO屬性。我們可以通過property屬性配置。 我們也可以通過Autowire讓spring自動注入。
Autowrire的幾個值:
No:不啟用自動裝配,這也是默認值。
byName: 通過屬性的名字的方式查找JavaBean依賴的對象並為其注入。
byType:通過屬性的類型查找JavaBean依賴的對象並為其注入。但是如果同一種類型出現多個bean就會出錯。
constructor:和byType一樣,也是通過類型查找依賴對象。但是是通過構造方法注入。
autodetect:在byType和constructor之間自動的選擇注入方式。 spring5.x已經沒有了
default:由上級標簽beans的default-autowire屬性確定。 spring 5.x已經沒有了
我們來一個一個看看:
修改我們的程序,為accountDAO准備一個接口:
1 package com.boxuewa.dk.demo2.dao; 2 /** 3 * @author 戴着假發的程序員 4 * 5 * @description 6 */ 7 public interface IAccountDAO { 8 public int save(String name); 9 }
准備兩個實現類:
1 import com.boxuewa.dk.demo2.dao.IAccountDAO; 2 3 /** 4 * @author 戴着假發的程序員 5 * 6 * @description 7 */ 8 public class AccountDAO_oracle implements IAccountDAO { 9 @Override 10 public int save(String name) { 11 System.out.println("AccountDAO_oracle-save->保存賬戶:"+name); 12 return 1; 13 } 14 }
import com.boxuewa.dk.demo2.dao.IAccountDAO; /** * @author 戴着假發的程序員 * * @description */ public class AccountDAO_mysql implements IAccountDAO { @Override public int save(String name) { System.out.println("AccountDAO_mysql-save->保存賬戶:"+name); return 1; } }
並且將兩個全部注冊在spring中
1 <!-- mysql-dao --> 2 <bean id="mysqlDAO" class="com.boxuewa.dk.demo2.dao.impl.AccountDAO_mysql"/> 3 <!-- oracle-dao --> 4 <bean id="oracleDAO" class="com.boxuewa.dk.demo2.dao.impl.AccountDAO_oracle"/>
修改service
1 import com.boxuewa.dk.demo2.dao.IAccountDAO; 2 3 /** 4 * @author 戴着假發的程序員 5 * 6 * @description 7 */ 8 public class AccountService { 9 private IAccountDAO mysqlDAO; 10 public void setMysqlDAO(IAccountDAO mysqlDAO) { 11 this.mysqlDAO = mysqlDAO; 12 } 13 14 public int save(String name){ 15 System.out.println("AccountService-save->保存用戶:"+name); 16 return mysqlDAO.save(name); 17 } 18 }
1 <!--service配置--> 2 <bean id="accountService" class="com.boxuewa.dk.demo2.service.AccountService" autowire="byName"/>
項目結構:

[1]byName值:通過屬性的名字的方式查找JavaBean依賴的對象並為其注入。
注意我們的配置:

service中的屬性名是mysqlDAO

很明顯spring按照名字幫我們注入了mysqlDAO。

[2]byType通過屬性的名字的方式查找JavaBean依賴的對象並為其注入。
注意我們的容器中有兩個IAccountDAO的實現bean,所以當我使用byType的時候,spring會報錯。
在idea中我們一旦將autowrie修改為byType,就會提示錯誤:

這個提示就是屬性mysqlDAO按照類型找到了兩個匹配的bean,但是應該是一個,所以報錯了。
我們注釋掉一個:

提示消失。
再測試:

[3]constructor:和byType一樣,也是通過類型查找依賴對象。但是是通過構造方法注入。
這是set方法已經無效了,我們需要提供對應的構造方法:

這個構造方法的要求就是:這個構造方法只能傳入要注入的屬性,其他屬性不能傳入。我們看看下面的幾個情況。
我們添加一個RoleDAO。
以下幾個構造方法都是合法的,spring都可以調用,並且注入注入屬性:
1 public AccountService(IAccountDAO accountDAO){ 2 this.accountDAO = accountDAO; 3 } 4 public AccountService(IRoleDAO roleDAO){ 5 this.roleDAO = roleDAO; 6 } 7 public AccountService(IAccountDAO accountDAO,IRoleDAO roleDAO){ 8 this.accountDAO = accountDAO; 9 this.roleDAO = roleDAO; 10 }
下面是一個spring無法調用的構造方法例子:
1 public AccountService(IAccountDAO accountDAO,IRoleDAO roleDAO,String otherArg){ 2 this.accountDAO = accountDAO; 3 this.roleDAO = roleDAO; 4 }
注意:只要類中有一個合法的構造方法,spring就會自動找到合法的構造方法調用,並且根據需求注入屬性。
[4] beans標簽的default-autowire
我們可以在beans標簽上通過default-autowire屬性統一配置當前beans中的所有bean的自動裝配方式。
注:當我們在bean中的autowire配置byName或者byType時,我們的類必須有無參數的構造方法。
