1. 程式人生 > >四、註解配置IOC、DI

四、註解配置IOC、DI

not base sca ali component interface service spa ret

1、註解 @Component

  我們這裏有個類 Person

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 對象,我們要進行如下配置:

  applicationContext.xml 配置:

1 <bean id="person" class="com.ys.annotation.Person"></bean>

  如果使用註解呢?

  第一步:在 applicationContext.xml 中引入命名空間

  技術分享圖片

  

  這裏我們簡單講解一下這裏引入的命名空間,簡單來說就是用來約束xml文件格式的。第一個 xmlns:context ,這表示標簽格式應該是 <context:標簽名>

  第二步:在 applicationContext.xml 文件中引入註解掃描器

1 2 <!-- 組件掃描,掃描含有註解的類 --> <context:component-scan base-package="com.ys.annotation"></context:component-scan>

  base-package:表示含有註解類的包名

  如果掃描多個包,則上面的代碼書寫多行,改變 base-package 裏面的內容即可!

  第三步:在 Person 類中添加註解@Component

  技術分享圖片

  第四步:測試

1 2 3 4 5 6 7 8 9 10 @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 註解的衍生註解,功能一樣

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

  

回到頂部

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

  

回到頂部

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

四、註解配置IOC、DI