Annotation(注解)是JDK1.5及以后版本引入的。它可以用於創建文檔,跟蹤代碼中的依賴性,甚至執行基本編譯時檢查。注解是以‘@注解名’在代碼中存在的。
前面講解 IOC 和 DI 都是通過 xml 文件來進行配置的,我們發現 xml 配置還是比較麻煩的,那么如何簡化配置呢?答案就是使用注解!
PS:本篇博客源碼下載鏈接:http://pan.baidu.com/s/1geBMPrX 密碼:z7ku
1、注解 @Component
我們這里有個類 Person
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 對象,我們要進行如下配置:
applicationContext.xml 配置:
<bean id="person" class="com.ys.annotation.Person"></bean>
如果使用注解呢?
第一步:在 applicationContext.xml 中引入命名空間
這里我們簡單講解一下這里引入的命名空間,簡單來說就是用來約束xml文件格式的。第一個 xmlns:context ,這表示標簽格式應該是 <context:標簽名>
第二步:在 applicationContext.xml 文件中引入注解掃描器
<!-- 組件掃描,掃描含有注解的類 --> <context:component-scan base-package="com.ys.annotation"></context:component-scan>
base-package:表示含有注解類的包名
如果掃描多個包,則上面的代碼書寫多行,改變 base-package 里面的內容即可!
第三步:在 Person 類中添加注解@Component
第四步:測試
@Test public void testAnnotation(){ //1、啟動 spring 容器 //2、從 spring 容器中取出數據 //3、通過對象調用方法 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") 這樣寫。
2、@Repository @Service @Controller
此外:下面三個注解是 @Component 注解的衍生注解,功能一樣
@Repository :dao層 @Service:service層 @Controller:web層
3、注解 @Resource
@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進行匹配,匹配成功,則賦值,不成功則報錯
4、注解 @Autowired
功能和注解 @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