咱們這裏有個類 Personhtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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 對象,咱們要進行以下配置:java
applicationContext.xml 配置:web
1
|
<bean id=
"person"
class
=
"com.ys.annotation.Person"
></bean>
|
若是使用註解呢?spring
第一步:在 applicationContext.xml 中引入命名空間app
這裏咱們簡單講解一下這裏引入的命名空間,簡單來講就是用來約束xml文件格式的。第一個 xmlns:context ,這表示標籤格式應該是 <context:標籤名>ide
第二步:在 applicationContext.xml 文件中引入註解掃描器函數
1
2
|
<!-- 組件掃描,掃描含有註解的類 -->
<context:component-scan base-
package
=
"com.ys.annotation"
></context:component-scan>
|
base-package:表示含有註解類的包名測試
若是掃描多個包,則上面的代碼書寫多行,改變 base-package 裏面的內容便可!ui
第三步:在 Person 類中添加註解@Componentthis
第四步:測試
1
2
3
4
5
6
7
8
9
10
|
@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 註解的衍生註解,功能同樣
1
2
3
|
@Repository
:dao層
@Service
:service層
@Controller
:web層
|
@Resource 註解,它能夠對類成員變量、方法及構造函數進行標註,完成自動裝配的工做。 經過 @Resource 的使用來消除 set ,get方法。
首先建立一個 學生類 Student.java
而後在 Person 類中添加一個屬性 Student
那麼咱們如何獲取 Person 對象,並調用 showStudent()方法呢?這個問題簡化就是如何給屬性 Student 實例化,也就是依賴注入
不使用註解:
1
2
3
4
|
<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
1
2
3
4
5
6
7
|
package
com.ys.autowired;
public
interface
PersonDao {
public
void
savePerson();
}
|
第二步:建立一個接口實現類 PersonDaoImplOne
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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