4、註解配置IOC、DI

一、註解 @Component

  咱們這裏有個類 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") 這樣寫。

 

二、@Repository    @Service   @Controller

  此外:下面三個註解是 @Component 註解的衍生註解,功能同樣

1
2
3
@Repository  :dao層
@Service :service層
@Controller :web層

  

 

三、註解 @Resource

  @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進行匹配,匹配成功,則賦值,不成功則報錯

  

 

 

四、註解 @Autowired

  功能和註解 @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

相關文章
相關標籤/搜索