Annotation(註解)是JDK1.5及之後版本引入的。它能夠用於建立文檔,跟蹤代碼中的依賴性,甚至執行基本編譯時檢查。註解是以‘@註解名’在代碼中存在的。java
前面講解 IOC 和 DI 都是經過 xml 文件來進行配置的,咱們發現 xml 配置仍是比較麻煩的,那麼如何簡化配置呢?答案就是使用註解!web
咱們這裏有個類 Personspring
package com.ys.annotation; public class Person { private int pid; private String pname; private String psex; public int getPid() { return pid; } public void setPid(int pid) { this.pid = pid; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public String getPsex() { return psex; } public void setPsex(String psex) { this.psex = psex; } }
若是咱們不使用註解,經過前面講解的,要想讓 Spring 容器幫咱們產生 Person 對象,咱們要進行以下配置:app
applicationContext.xml 配置:ide
<bean id="person" class="com.ys.annotation.Person"></bean>
若是使用註解呢?函數
第一步:在 applicationContext.xml 中引入命名空間測試
這裏咱們簡單講解一下這裏引入的命名空間,簡單來講就是用來約束xml文件格式的。第一個 xmlns:context ,這表示標籤格式應該是 <context:標籤名>ui
第二步:在 applicationContext.xml 文件中引入註解掃描器this
<!-- 組件掃描,掃描含有註解的類 --> <context:component-scan base-package="com.ys.annotation"></context:component-scan>
base-package:表示含有註解類的包名
若是掃描多個包,則上面的代碼書寫多行,改變 base-package 裏面的內容便可!
第三步:在 Person 類中添加註解@Component
第四步:測試
@Test public void testAnnotation(){ //一、啓動 spring 容器 //二、從 spring 容器中取出數據 //三、經過對象調用方法 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) context.getBean("person"); System.out.println(person.getPname()); }
若是看完上面的註解配置,你一臉懵逼,那不要緊,咱們下面來詳細講解。
@Component
若是一個類上加了@Component註解,就會進行以下的法則
若是其value屬性的值爲""
@Component
public class Person {}
等價於
<bean id="person" class="..Person">
若是其value屬性的值不爲""
@Component("p")
public class Person {}
等價於
<bean id="p" class="..Person">
那麼這就很好理解測試程序中,咱們直接 context.getBean("person") 這樣寫。
此外:下面三個註解是 @Component 註解的衍生註解,功能同樣
@Repository :dao層
@Service:service層
@Controller:web層
@Resource 註解,它能夠對類成員變量、方法及構造函數進行標註,完成自動裝配的工做。 經過 @Resource 的使用來消除 set ,get方法。
首先建立一個 學生類 Student.java
而後在 Person 類中添加一個屬性 Student
那麼咱們如何獲取 Person 對象,並調用 showStudent()方法呢?這個問題簡化就是如何給屬性 Student 實例化,也就是依賴注入
不使用註解:
<property name="students"> <ref bean="student"/> </property> <bean id="student" class="com.ys.annotation_di.Student"></bean>
使用註解:
@Resource註解之後,判斷該註解name的屬性是否爲""(name沒有寫)
①、若是沒有寫name屬性,則會讓屬性的名稱的值和spring配置文件bean中ID的值作匹配(若是沒有進行配置,也和註解@Component進行匹配),若是匹配成功則賦值,若是匹配不成功,則會按照spring配置文件class類型進行匹配,若是匹配不成功,則報錯
②、若是有name屬性,則會按照name屬性的值和spring的bean中ID進行匹配,匹配成功,則賦值,不成功則報錯
功能和註解 @Resource 同樣,能夠對類成員變量、方法及構造函數進行標註,完成自動裝配的工做。只不過註解@Resource 是按照名稱來進行裝配,而@Autowired 則是按照類型來進行裝配。
第一步:建立接口 PersonDao
package com.ys.autowired; public interface PersonDao { public void savePerson(); }
第二步:建立一個接口實現類 PersonDaoImplOne
package com.ys.autowired; import org.springframework.stereotype.Component; @Component("personDaoImplOne") public class PersonDaoImplOne implements PersonDao{ @Override public void savePerson() { System.out.println("save Person One"); } }
第三步:建立PersonService
package com.ys.autowired; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("personService") public class PersonService{ @Autowired private PersonDao personDao; public void savePerson() { this.personDao.savePerson(); } }
注意:這裏咱們在 private PesronDao personDao 上面添加了註解 @Autowired,它首先會根據類型去匹配,PersonDao 是一個接口,它的實現類是 PesronDaoImpOne,那麼這裏的意思就是:
PersonDao personDao = new PersonDaoImpOne();
那麼問題來了,若是 PersonDao 的實現類有多個呢?咱們建立第一個實現類 PersonDaoImpTwo
package com.ys.autowired; import org.springframework.stereotype.Component; @Component("personDaoImplTwo") public class PersonDaoImplTwo implements PersonDao{ @Override public void savePerson() { System.out.println("save Person Two"); } }
若是仍是向上面那樣寫,那麼測試就會報錯。怎麼解決呢?
第一種方法:更更名稱
第二種方法:@Autowired 和 @Qualifier("名稱") 配合使用
在使用@Autowired時,首先在容器中查詢對應類型的bean
若是查詢結果恰好爲一個,就將該bean裝配給@Autowired指定的數據
若是查詢的結果不止一個,那麼@Autowired會根據名稱來查找。
若是查詢的結果爲空,那麼會拋出異常。解決方法時,使用required=false