Spring之容器和配置初識


通過前兩篇文章的學習,對spring有了初步的認識,並且應該認識到,spring的核心在於控制反轉IOC和依賴注入DI

spring是怎麼達到這個目標呢?

我們都已經知道理利用spring框架,依賴的注入由spring容器來進行,那麼當然需要一些配置信息來告訴spring怎麼注入。這就是spring元數據的配置(即bean的配置)。

綜上,spring通過容器和元數據的配置來實現基本的功能。

通過本文達到,兩個目標:

1.初步的認識spring容器。

2.初步認識spring元數據的配置

ApplicationContext

接口 org.springframework.context.ApplicationContext 代表了Spring IoC容器,它負責實例化、配置、組裝beans. Spring通過讀取元數據的配置進行以上的操作,元數據的配置有多種形式,包括xml、註解和JSR標準。

且Spring 提供了幾種ApplicationContext的實現,如ClassPathXmlApplicationContext、FileSystemXmlApplicationContext,顧名思義,它們讀取基於xml的元數據配置。

程序示例

說明

下面通過一個簡單的例子說明spring容器的簡單用法和spring XMl元數據配置。

這個例子很簡單,就是獲取系統中的用戶,然後打印出來。整個程序分爲三各層次,模擬dao、service和客戶端,客戶端調用service,service調用dao。Service對dao的依賴由spring容器來管理。代碼結構如下圖:



代碼

代碼由客戶端調用開始,一點點深入底層,其中的註釋詳細的說明了相關的要點。

首先是User類:


public class User {
 
    public int id;
   
    public String name;
 
    /**
     * @param id
     * @param name
     */
    public User(int id, String name) {
       super();
       this.id = id;
       this.name = name;
    }
 
    @Override
    public String toString() {
       return "User [id=" + id + ", name=" + name + "]";
    }
    }


客戶端

客戶端由main函數調用模擬,代碼如下:

package com.test;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.test.service.UserService;
 
/**  

 * @Description: 客戶端首先初始化spring容器,然後從容器中獲取benn調用其相應方法。和傳統不一樣的地方在於,
 * 業務對象UserService 的實例化不是由客戶端通過new 來產生,而是直接從spring容器中獲取。
 *
 * 本示例例環境爲eclipse
 */
public class TestMain {
    public static void main(String[] args) {
       /**
        * ApplicationContext代表spring容器,而ClassPathXmlApplicationContext是它的一個實現,它從類路徑下讀取相應的
        *  xml 元數據配置,並初始化容器。其中allbean.xml是相應的元數據配置
        */
       ApplicationContext context = new ClassPathXmlApplicationContext("allbean.xml");
      
       //從容器中獲取名稱爲 user 的 userService 對象,這個名稱在配置文件之後配置。
       UserService userService = context.getBean("user", UserService.class);
      
       System.out.println(userService.getUser());
 
 
       //可以和傳統方式相比較:
      
//     UserService user = new UserServiceIml();
//     UserDao dao = new UserDaoImp();
//     ((UserServiceIml)user).setUserDao(dao);
//    
//     System.out.println(user.getUser());
      
    }
 
}

allbean.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <!--
    此配置文件是spring 元數據的配置文件,根標籤爲 beans標籤。
    在這個標籤下可以定義由Spring 管理的 bean,其定義形式如下被註釋的地方所示:
    基本的配置包括一個容器全局唯一的字符串id,和一個完全限定的類名。
   
    但在這個例子中,有兩個import標籤,分別引入了另外兩個 xml元數據配置文件。
    這麼做的好處是,不同的 bean定義對應相應的程序體系架構。
  import標籤導入的配置文件路徑是相對路徑,相對於當前文件。
 
  路徑前面可以與斜槓,但不建議這麼做。如下示例不推薦使用
      <import resource="/com/test/dao/dao.xml"/>
 
  類似../的路徑也不推薦使用
   
     -->
    <import resource="com/test/dao/dao.xml"/>
   
    <import resource="com/test/service/service.xml"/>
   
    <!--
    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
     -->
   
   
</beans>

Service

Service層包含一個接口,一個實現類,一個Spring的xml元數據配置文件:

如下


/**  
 
 * 接口
 */
public interface UserService {
   
    public List<User> getUser();
 
}
/**  
 *實現類,有個字段引用了UserDao接口,其具體的業務邏輯調用  {@link UserDao#getUser()}實現
 *
 *且有一個set方法,此set方法由spring 容器注入使用,如果沒有回報錯,
 *這是spring容器依賴注入的一種方法--setter注入
 */
public class UserServiceIml implements UserService{
   
    private UserDao userDao;
    @Override
    public List<User> getUser() {
       return userDao.getUser();
    }
    public void setUserDao(UserDao userDao) {
       this.userDao = userDao;
    }
}


Xml元數據配置如下,它定義了userServicebean,且定義了它的依賴:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <!--
    定義了一個由Spring管理的  id爲 user 類型爲com.test.service.UserServiceIml 的 bean,
    property 標籤用來定義setter 依賴。
   name 屬性  定義依賴的名稱爲  “userDao”(以便通過反射得到seeter方法),此名稱和 UserServiceIml 的字段userDao對應。
   ref屬性定義此依賴引用了一個名稱爲 “userDao”的bean (這個bean在dao層定義)
     -->
   
    <bean id="user" class="com.test.service.UserServiceIml" >
        <property name="userDao" ref="userDao"></property>
    </bean>
 
</beans>

Dao

Dao層定義了相應的 接口,實現類和 xml元數據配置,首先是接口和實現類:

public interface UserDao {
   
    public List<User> getUser();
 
 
}
public class UserDaoImp implements UserDao{
 
   
   
    @Override
    public List<User> getUser() {
       List<User> res = new ArrayList<User>();
       User a = new User(1, "aa");
       User b = new User(2, "bb");
      
       res.add(a);
       res.add(b);
       return res;
    }
   
}

然後是xml配置文件,定義了一個名稱爲userDao,實現類爲com.test.dao.UserDaoImp 的bean:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <bean id="userDao" class="com.test.dao.UserDaoImp">
    </bean>
 
</beans>

輸出

運行客戶端程序,輸入如下,和預期一樣:


總結

此文章簡單的說明了Spring容器的用法和相關bean的配置。從一個極簡單例子入手,自頂向下的進行剖析,並簡單的分析了Spring的優點。當然本人目前水平有限,不當之處,歡迎指正。

另外,關於Spring bean的配置還有很多地方需要深入理解,不僅僅是Xml,還有註解、JSR以及他們的組合。bean的配置也包含其他方面,如基本數據類型、集合類型、生命週期、範圍、容器擴展點等,而這些都屬於spring的核心功能,需要逐步理解掌握,期待大家共同進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章