Spring詳解(四)------註解配置IOC、DI

 


  Annotation(註解)是JDK1.5及之後版本引入的。它能夠用於建立文檔,跟蹤代碼中的依賴性,甚至執行基本編譯時檢查。註解是以‘@註解名’在代碼中存在的。java

  前面講解 IOC 和 DI 都是經過 xml 文件來進行配置的,咱們發現 xml 配置仍是比較麻煩的,那麼如何簡化配置呢?答案就是使用註解!web

一、註解 @Component

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

二、@Repository    @Service   @Controller

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

@Repository :dao層
@Service:service層
@Controller:web層
  

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

 

四、註解 @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

相關文章
相關標籤/搜索