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


  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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM