亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

首頁 慕課教程 Spring 入門教程 Spring 入門教程 Spring DI(依賴注入)之注解配置

Spring DI(依賴注入)之注解配置

1. 前言

上一節,我們通過 xml 文件的配置方式,實現了對多種依賴類型的注入,當然體會到了 xml 文件配置方式的弊端:有一點麻煩。

依賴注入是有兩種方式,一種是 xml ,另外一種就是注解的配置方式。

本節,我們演示下通過注解配置這種方式來實現注入依賴。

來吧 ,直入主題,莫浪費大好光陰…

2. 工程實例

2.1 注解的介紹

在正式使用注解之前,我們首先介紹下注解語法以及它的作用。

  • @Autowired: 此注解自動按照類型注入。從容器中尋找符合依賴類型的實例,當使用該注解注入屬性時,set 方法可以省略。但是因為按照類型匹配,如果容器中有多個匹配的類型,會拋出異常,需要指定引入的實例 id。如果找不到匹配的實例,那么也會拋出異常;
  • @Qualifier: 此注解不能單獨使用,它的作用是在按照類型注入的基礎之上,再按照 Bean 的 id 注入。所以如果是使用了 @Autowire 注解自動注入,但是容器中卻有多個匹配的實例,可以搭配此注解,指定需要注入的實例 id;
  • @Resource 此注解的作用是指定依賴按照 id 注入,還是按照類型注入。當只使用注解,但是不指定注入方式的時候,默認按照 id 注入,找不到再按照類型注入。

2.2 @Autowired 注解

1. 為了測試效果,我們創建 Service 和 Dao 兩個類, Dao 作為 Service 的依賴。代碼如下:

//service實現類的代碼
@Service
public class UserServiceImpl implements  UserService {

    @Autowired
    private UserDao userDao;

    public void saveUser() {

        System.out.println("執行service中的保存邏輯");
    }
}

//dao實現類的代碼
@Repository
public class UserDaoImpl implements  UserDao {

    public void saveUser() {
        System.out.println("執行dao的保存方法");
    }
}

代碼解釋:

上面代碼可以看到,兩個類的實例化方式都是通過注解注入到容器, 并且在 service 實現類中的 userDao 屬性上面加了注解 @Autowired。

我們首先測試下:能否通過這個注解,實現依賴注入,另外再測試下它是否是按照類型注入。

2. 配置文件的內容為注解實現 IoC。

圖片描述

配置文件解釋: 注解實現 IoC 的章節說過,需要通過組件掃描來實例化容器。

3. 編寫測試代碼

public class SpringAnTest {

    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        UserService userService = context.getBean(UserService.class);
        userService.saveUser();

    }
}

測試結果:

圖片描述

結果解釋

可以看到 service 中的代碼執行,并且通過 dao 的示例調用的方法也執行了,那么說明 @Autowired 注解實現了屬性 userDao 的注入。

當然這種操作是小兒科,沒有一個同學覺得他有什么。 我們驗證下它的特點:set 方法我們是省略了,那么它是否按照類型注入的呢?

如果我們的實現類中有多個 userDao 接口的實現類呢,又該如何呢?

4. 添加 UserDaoImpl2 一樣實現 userDao 的接口,代碼如下:

@Repository
public class UserDaoImpl1 implements  UserDao {

    public void saveUser() {
        System.out.println("執行dao1的保存方法");
    }
}

測試結果

圖片描述

結果解釋:

可以看到上面控制臺打印的異常堆棧信息,清楚的提示錯誤原因,沒有指定的 bean 實例 UserDao 類型的,期待單個 bean 匹配,但是找到了兩個。

一個是 userDaoImpl 一個是 userDaoImpl1??吹竭@可以證明: @Autowired 注解是按照類型注入,如果匹配的類型多了就會報錯。

疑問導出:

難道使用了 Spring 框架以后,我們的接口只能有一個實現類嗎? 當然不可能,畢竟我們看 Spring 的源碼的時候 已經看到了,很多的接口對應一大堆的實現類。

那么,針對這種多個接口實例的情況,怎么解決的呢?繼續我們注解的學習。

2.3 @Qualifier 注解

1. 此注解的作用,我們介紹過了,這里再看一下:它的作用是在按照類型注入的基礎之上,再按照 Bean 的 id 注入,不能單獨使用,搭配上面的 @Autiwired 注解。

在兩個實現類的基礎之上改造代碼如下:

@Service
public class UserServiceImpl implements  UserService {

    @Qualifier("userDaoImpl")
    @Autowired
    private UserDao userDao;

    public void saveUser() {

        System.out.println("執行service中的保存邏輯");
        userDao.saveUser();
    }
}

代碼解釋

在屬性注入的地方,通過注解 @Qualifier 的參數,指定了注入的 bean 實例 id 為 userDaoImpl。

2. 測試方法繼續執行查看結果。

圖片描述

結果解釋:

那么可以看到,我們的方法正常執行,而且執行的就是 userDaoImpl 中的方法。

3. 繼續改造 service 的代碼如下,將 @Qualifier 注解中的值換成 userDaoImpl1 以后再看看結果。

@Service
public class UserServiceImpl implements  UserService {

	@Qualifier("userDaoImpl1")
	@Autowired
	private UserDao userDao;

	public void saveUser() {

   	 	System.out.println("執行service中的保存邏輯");
    	userDao.saveUser();
	}

}

結果如下:

圖片描述

通過修改 @Qualifier 注解中 id 的屬性值 ,可以分別注入不同的實現類,那么證明了 @Qualifier 注解的作用。

2.4 @Resources 注解

此注解的作用是指定依賴按照 id 注入,還是按照類型注入。當只使用注解,但是不指定注入方式的時候,默認按照 id 注入,找不到時再按照類型注入。

語法如下:

@Resource   //默認按照 id 為 userDao的bean實例注入    
@Resource(name="userDao")  //按照 id 為 userDao的bean實例注入    
@Resource(type="UserDao")  //按照 類型 為 UserDao的bean實例注入    
    

這里就只做個語法的介紹,注解的使用大同小異,大家按照上方步驟自行測試即可。

3. 小結

本節重點講解注解注入依賴的使用,咱們做個總結:

1. 常用的注解有 3 種 :@Autowired @Qualifier @Resources

2. 注解注入的形式兩種 : 按照 bean 的 id 注入,或者按照 bean 的類型注入;

3. 哪種注解的目的,都是為了成功的注入使用的依賴,所以為了我們的開發服務,大家靈活使用即可。

不費力氣就能得到的… 只有年齡。