使用xml方式實現自動檢測和依賴注入需要進行繁瑣的xml配置,主要包括兩個部分:
(1)使用<bean>...</bean>進行bean的聲明;
(2)使用<property>...</property>或者<constructor-arg>...</constructor-arg>進行setter或者構造器的依賴注入
當bean數量比較少時,xml配置比較簡單,但是當bean數量非常多,bean和bean之間的依賴也非常複雜,這時候再使用xml配置就會非常繁瑣,維護起來也相當複雜,使用註解就相對要簡單一些。
還是針對以上兩個問題:
(1)Spring框架提供了bean的自動檢測來解決bean的聲明問題;
(2)Spring框架提供了自動裝配功能來解決屬性的依賴注入;
1、bean的自動檢測
Spring框架提供了以下五種特殊註解來標註類。
@Component -- Spring框架通用的註解,一般用來標註不好歸類的類。
@Controller -- 專用於Spring MVC的控制器註解
@Service -- 標識該類爲服務
@Repository -- 標識將該類定義爲數據倉庫
被@Component註解標註的自定義註解
當某一個類被以上註解所標註,並且在Spring的xml文件中做一些配置(具體的配置稍後會提到),Spring框架就會自動將該類識別爲一個bean並將其註冊到容器中。下面這個例子就是將OracleDaoImpl用@Repository標註爲數據倉庫,當框架啓動時,就會將該類當作一個bean註冊到容器中。
package com.springframework.ioc;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
@Repository
public class OracleDaoImpl implements MyDao{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
@Override
public void addUser(){
System.out.println("this is " + name + " add user...");
}
}
可以看到以上OracleDaoImpl類是MyDao的一個子類,MyDao類有時不止有一個實現類,除了OracleDaoImpl之外還有一個MySqlDaoImpl實現類,同樣也將這個類用@Repository標註。如下:
package com.springframework.ioc;
import java.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
@Repository
public class MysqlDaoImpl implements MyDao{
private String name;
private int id;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
@Override
public void addUser(){
System.out.println("this is " + name + " id is " + id + " add user...");
}
}
這個時候就會有一個問題,我該如何區分這兩個bean呢?在xml配置中,我們會根據bean的id來區分,同樣在也可使用註解加bean id來進行區分,修改如下:
package com.springframework.ioc;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
@Repository("OracleDao")
public class OracleDaoImpl implements MyDao{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
@Override
public void addUser(){
System.out.println("this is " + name + " add user...");
}
}
將OracleDaoImpl類聲明爲id爲“OracleDao”的bean。
package com.springframework.ioc;
import java.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
@Repository("MysqlDao")
public class MysqlDaoImpl implements MyDao{
private String name;
private int id;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public MysqlDaoImpl(){
}
public MysqlDaoImpl(String name, int id){
this.name = name;
this.id = id;
}
@Override
public void addUser(){
System.out.println("this is " + name + " id is " + id + " add user...");
}
}
將MysqlDaoImpl聲明爲id爲“MysqlDao”的bean。
這個時候就可以通過bean的id來對bean進行區分,也就爲後面的自動裝配做好鋪墊。
前面說到,要使用bean的自動檢測功能,需要對xml文件進行一下配置,如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" default-lazy-init="true"> <!--對所有bean進行延遲初始化--> <!-- 自動掃描bean 自動裝配bean --> <context:component-scan base-package="com.springframework.ioc"/> </beans>
使用
<context:component-scan base-package="com.springframework.ioc"/>
來指出需要自動檢測的包即可。
二、自動裝配
在自動檢測完成bean,將bean註冊到容器中後,接下來的任務就是自動裝配了。
Spring框架提供了註解@Autowired標註屬性、setter方法或者是構造器來解決對象的依賴問題,舉例,要在service層調用dao層,則如下所示:
package com.springframework.ioc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service("myService2")
public class MyService2{
@Autowired
@Qualifier("OracleDao")
private MyDao myDao;
public MyDao getMyDao() {
return myDao;
}
}
可以看到,在service層有一個myDao屬性,使用@Autowired和@Qualifier來自動裝配bean,其中:
使用@Autowired註解表明是自動裝配,使用@Qualifier註解來指出要裝配的bean的id,以便匹配。
另外需要說明的是:使用的這些註解都是Spring框架提供的,這樣代碼就會和Spring框架耦合比較大,可以使用基於Java的註解@Inject 和@Named() 分別對應@Autowired和@Qualified()