天天看點

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

文章目錄

(一)常用IOC注解按作用分類

(二)用于建立對象的注解

(三)由Component衍生的注解

(四)自動按照類型注入

(五)用于注入資料的注解

(六)改變作用範圍的注解

(七)與生命周期相關的注解

(一)常用IOC注解按作用分類

學習基于注解的 IoC 配置,大家腦海裡首先得有一個認知:
		即注解配置和 xml 配置要實作的功能都是一樣的(隻是形式不一樣),都是要降低程式間的耦合
關于實際的開發中到底使用xml還是注解,每家公司有着不同的使用習慣,是以這兩種配置方式我們都需要掌握
           

建立一個普通的maven項目,并且被bean.xml的配置注釋掉

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

曾經XML的配置:

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"
      scope=""  init-method="" destroy-method="">
      <property name=""  value="" | ref=""></property>
</bean>
           

注解的分類:

  1. 用于建立對象的
    作用:他們的作用就和在XML配置檔案中編寫一個<bean>标簽實作的功能是一樣的
               
  2. 用于注入資料的
    作用:他們的作用就和在xml配置檔案中的bean标簽中寫一個<property>标簽的作用是一樣的
               
  3. 用于改變作用範圍的
    作用:他們的作用就和在bean标簽中使用scope屬性實作的功能是一樣的
               
  4. 和生命周期相關的
    作用:他們的作用就和在bean标簽中使用init-method和destroy-methode的作用是一樣的
               

(二)用于建立對象的注解

使用建立對象的注解效果跟在XML配置檔案中編寫一個

<bean>标簽

實作的功能是一樣的

@Component:
	作用:用于把目前類對象存入spring容器中
	屬性:
		value:用于指定bean的id。當我們不寫時,它的預設值是目前類名,且首字母改小寫
           

嘗試使用

@Component

注解,不加任何參數,預設就是首字母改小寫的類名

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

但是會發現報錯了,原因如下:

(我們已經提前把bean.xml的相關标簽都注釋掉了)

//1.擷取核心容器對象
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
           

ClassPathXmlApplicationContext初始化容器時會把bean.xml中聲明的标簽下的類都建立到容器中

但是因為bean.xml并不知道哪一個類加上注解了,是以無法建立對象

我們要在bean.xml告知spring在建立容器時要掃描的包

配置所需要的标簽不是在bean.xml的限制中,而是在一個名稱為context的名稱空間的限制中

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解
Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

然後加上标簽指明要掃描的包

運作效果如下:

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

我們可以自定義value的值

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

當然注解隻有一個參數,且參數為value時可以使用省略寫法

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

(三)由Component衍生的注解

@Controller:一般用在表現層
@Service:一般用在業務層
@Repository:一般用在持久層
以上三個注解他們的作用和屬性與@Component是一模一樣
他們三個是spring架構為我們提供明确的三層使用的注解,使我們的三層對象更加清晰
           

原理:其實接口就是類,上面的Component類是父類,現在這三個分别是它的子類,隻繼承,不重寫

我們接下來改寫業務層的注解,讓它更規範,并且增加持久層的注解

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

運作試試

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

(四)自動按照類型注入

我們上一篇部落格提到一個問題:業務層實作類如何調用持久層的方法?

我們最後是配置了xml解決這個問題,現在嘗試用注解去解決

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

可以使用

@Autowired

注解實作自動按照類型注入,如下:

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

運作試試:

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

原理如下:

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

容器中有唯一的一個bean對象類型和要注入的變量類型比對,就可以注入成功

詳細過程:首先會找到實作類,但是因為實作類繼承了接口,是以可以把實作類看作接口(多态)

那麼如果ioc容器中有多個類型比對呢?

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

預設情況下會報錯,如下:

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

但是下面這兩種情況也是有多個比對類型,但是卻不報錯,如下:

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解
Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

總結:

  1. 如果有唯一一個比對時,就直接注入
  2. 如果有多個比對時,首先按照類型篩選出來比對的對象

    然後使用變量名稱作為bean的id,然後繼續篩選

    如果兩次篩選後有唯一比對的,可以注入成功;否則失敗

(五)用于注入資料的注解

使用注入資料注解的效果跟在xml配置檔案中的bean标簽中寫一個

<property>标簽

的作用是一樣的

@Autowired:
	作用:
		自動按照類型注入
			如果容器中有唯一的一個bean對象類型和要注入的變量類型比對,就可以注入成功
			如果ioc容器中沒有任何bean的類型和要注入的變量類型比對,則報錯
			如果ioc容器中有多個類型比對時(上面有詳解,這裡不再重複)
	出現位置:
		可以是變量上,也可以是方法上
	細節:
		在使用注解注入時,set方法就不是必須的了
===================================================================================
@Qualifier:
	作用:
		在按照類中注入的基礎之上再按照名稱注入
		它在給類成員注入時不能單獨使用;但是在給方法參數注入時可以(見:Spring之新注解(六))
	屬性:
		value:用于指定注入bean的id
===================================================================================		
@Resource
	作用:
		直接按照bean的id注入。它可以獨立使用
	屬性:
		name:用于指定bean的id
		
以上三個注入都隻能注入其他bean類型的資料,而基本類型和String類型無法使用上述注解實作
另外,集合類型的注入隻能通過XML來實作
===================================================================================			 
@Value
	作用:
		用于注入基本類型和String類型的資料
	屬性:
		value:用于指定資料的值。它可以使用spring中SpEL(也就是spring的el表達式)
		SpEL的寫法:${表達式}
           

先看看

@Qualifier

,它可以在按照類中注入的基礎之上再按照名稱注入

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

一般用來處理多種比對結果的情況;另一種accountDao2的情況就不示範了

注意:在給類成員注入時,必須與Autowired注解配對使用,不能單獨使用,否則會空指針異常

(在給方法參數注入時可以單獨使用,後面會介紹)

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

我們單獨使用

@Autowired

時需要改變變量名;使用

@Qualifier

時又不能單獨使用,那有沒有更友善的注解呢?下面介紹

@Resource

其中的name屬性用于指定bean的id,此時不是value屬性了,是以不能使用省略寫法

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

但是

@Resource

也存在缺點,包括前面的

@Autowired

@Qualifier

都存在一些共同的缺點:

  1. 這三個注解都隻能注入其他bean類型的資料,而基本類型和String類型無法使用上述注解實作
  2. 另外,集合類型的注入隻能通過XML來實作

集合類型無法用注解注入我們可以略過,但是我們該如何用注解注入基本類型和String類型呢?我們可以用

@Value

注解實作

value:用于指定資料的值。它可以使用spring中SpEL(也就是spring的el表達式)
SpEL的寫法:${表達式}
           

具體用法這裡不再展示了,詳情可以見後面的綜合案例

(六)改變作用範圍的注解

使用改變作用範圍的注解的作用跟在

bean标簽

中使用scope屬性實作的功能是一樣的

@Scope:
	作用:用于指定bean的作用範圍
	屬性:
		value:指定範圍的取值。常用取值:singleton(單例)、prototype(多例)
           

注意:不寫該注解的話,預設情況下是單例的

下面示範一下多例的情況

Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解

(七)與生命周期相關的注解

使用與生命周期相關的注解的作用跟在

bean标簽

中使用init-method和destroy-methode的作用是一樣的

@PreDestroy
	作用:用于指定銷毀方法
@PostConstruct
	作用:用于指定初始化方法
           
Spring之常用的注解(四)文章目錄(一)常用IOC注解按作用分類(二)用于建立對象的注解(三)由Component衍生的注解(四)自動按照類型注入(五)用于注入資料的注解(六)改變作用範圍的注解(七)與生命周期相關的注解