1. 程式人生 > >初學spring框架和小練習

初學spring框架和小練習

Spring第一天

  1. Spring概述

1.1程式的耦合和解耦

      1.  什麼是程式的耦合

我們在開發中,會寫很多的類,而有些類之間不可避免的產生依賴關係,這種依賴關係稱之為耦合。有些依賴關係是必須的,有些依賴關係可以通過優化程式碼來解除的。請看下面的示例程式碼:

/**

* 客戶的業務層實現類依賴customerDao類,這兩個類就稱為耦合

*/

public class CustomerServiceImpl implements ICustomerService {

private ICustomerDao customerDao = new CustomerDaoImpl();

}

上面的程式碼表示:業務層呼叫持久層,並且此時業務層在依賴持久層的介面和實現類。如果此時沒有持久層實現類,編譯將不能通過。這種依賴關係就是我們可以通過優化程式碼解決的。

再比如:

下面的程式碼中,我們的類依賴了 MySQL 的具體驅動類,如果這時候更換了資料庫品牌,我們需要改原始碼來修改資料庫驅動。這顯然不是我們想要的。

public class JdbcDemo1 {

/**

* JDBC 操作資料庫的基本入門中存在什麼問題?

* 導致驅動註冊兩次是個問題,但不是嚴重的。

* 嚴重的問題:是當前類和 mysql 的驅動類有很強的依賴關係。

* 當我們沒有驅動類的時候,連編譯都不讓。

* 那這種依賴關係,就叫做程式的耦合

*

* 我們在開發中,理想的狀態應該是:

* 我們應該盡力達到的:編譯時不依賴,執行時才依賴。

*/

public static void main(String[] args) throws Exception {

//1.註冊驅動

//DriverManager.registerDriver(new com.mysql.jdbc.Driver());

Class.forName("com.mysql.jdbc.Driver");

//2.獲取連線

//3.獲取預處理 sql 語句物件

//4.獲取結果集

//5.遍歷結果集

}

      1.  解決程式耦合的思路

當是我們講解 jdbc 時,是通過反射來註冊驅動的,程式碼如下:

Class.forName("com.mysql.jdbc.Driver");

這時的好處是,我們的類中不再依賴具體的驅動類,此時就算刪除 mysql 的驅動 jar 包,依然可以編譯。但是因為沒有驅動類,所以不能執行。

不過,此處也有個問題,就是我們反射類物件的全限定類名字串是在 java 類中寫死的,一旦要改還是要修改原始碼。

解決這個問題也很簡單,使用配置檔案配置。

      1. 工廠模式解耦

在實際開發中我們可以把所有的 dao mapper 和 service 和 action web controller物件使用配置檔案配置起來,當啟動伺服器應用載入的時候,通過讀取配置檔案,把這些物件創建出來 並存起來。在接下來的使用的時候,直接拿過來用就好了。

1.1.4 控制反轉-Inversion Of Control

1 、存哪去?

分析:由於我們是很多物件,肯定要找個集合來存。這時候有 Map 和 List 供選擇。

到底選 Map 還是 List 就看我們有沒有查詢需求。有查詢需求,選 Map。

所以我們的答案就是

在應用載入時,建立一個 Map,用於存放 action,Service 和 dao 物件。

我們把這個 map 稱之為 容器。

2、還是沒解釋什麼是工廠?

工廠就是負責給我們從容器中獲取指定物件的類。這時候我們獲取物件的方式發生了改變。

原來:

我們在獲取物件時,都是採用 new 的方式。是主動的。

現在:

我們獲取物件時,同時跟工廠要,有工廠為我們查詢或者建立物件。是被動的。

這種被動接收的方式獲取物件的思想就是控制反轉,它是 spring 框架的核心之一。

它的作用只有一個:削減計算機程式的耦合。

    1.  Spring介紹
      1. Spring 概述

Spring框架有兩大核心 分別是IOC(控制反轉)和AOP(面向切面程式設計)

1.2.1.1 Spring簡介

Spring 是分層的 Java SE/EE 應用 full-stack 輕量級開源框架,以 IoCInverse Of Control

反轉控制)和 AOPAspect Oriented Programming:面向切面程式設計)為核心,提供了展現層 SpringMVC 和持久層 Spring JDBC 以及業務層事務管理等眾多的企業級應用技術,還能整合開源世界眾多著名的第三方框架和類庫,逐漸成為使用最多的 Java EE 企業應用開源框架。

1.2.1.2 Spring的發展歷程

1997 年 IBM 提出了 EJB 的思想

1998 年,SUN 制定開發標準規範 EJB1.0

1999 年,EJB1.1 釋出

2001 年,EJB2.0 釋出

2003 年,EJB2.1 釋出

2006 年,EJB3.0 釋出

Rod Johnson spring  之父)

Expert One-to-One J2EE Design and Development(2002)

闡述了 J2EE 使用 EJB 開發設計的優點及解決方案

Expert One-to-One J2EE Development without EJB(2004)

闡述了 J2EE 開發不使用 EJB 的解決方式(Spring 雛形)

      1.  Spring的優勢

方便解耦,簡化開發

通過 Spring 提供的 IoC 容器,可以將物件間的依賴關係交由 Spring 進行控制,避免硬編碼所造成的過度程式耦合。使用者也不必再為單例模式類、屬性檔案解析等這些很底層的需求編寫程式碼,可以更專注於上層的應用。

AOP  程式設計的支援

通過 Spring 的 AOP 功能,方便進行面向切面的程式設計,許多不容易用傳統 OOP 實現的功能可以通過 AOP 輕鬆應付。

宣告式事務的支援

可以將我們從單調煩悶的事務管理程式碼中解脫出來,通過宣告式方式靈活的進行事務的管理,提高開發效率和質量。

方便程式的測試

可以用非容器依賴的程式設計方式進行幾乎所有的測試工作,測試不再是昂貴的操作,而是隨手可做的事情。

方便整合各種優秀框架

Spring 可以降低各種框架的使用難度,提供了對各種優秀框架(Struts、Hibernate、Hessian、Quartz 任務排程框架  等)的直接支援。低 降低 JavaEE API  的使用難度Spring 對 JavaEE API(如 JDBC、JavaMail、遠端呼叫  CXF 等)進行了薄薄的封裝層,使這些 API 的使用難度大為降低。

Java  原始碼是經典學習範例

Spring 的原始碼設計精妙、結構清晰、匠心獨用,處處體現著大師對 Java 設計模式靈活運用以及對 Java 技術的高深造詣。它的原始碼無意是 Java 技術的最佳實踐的範例。

 

 

 

      1.  Spring的體系結構

 

      1.  Spring開發包

官網:http://spring.io/

下載地址:

http://repo.springsource.org/libs-release-local/org/springframework/spring

解壓:(Spring 目錄結構:)

* docs  :API 和開發規範.

* libs  :jar 包和原始碼.

* schema :約束.

我們上課使用的版本是Spring 4.2.4

  1. 使用Spring的IOC解決程式耦合

2.1案例的前期準備

本章我們使用的案例是,客戶的業務層和持久層的依賴關係解決。在開始 spring 的配置之前,我們要先準備一下環境。由於我們是使用 spring 解決依賴關係,並不是真正的要做增刪改查操作,所以此時我們沒必要寫實體類。並且我們在此處使用的是 java 工程,不是 java web 工程。

2.1.1 建立業務層介面和實現類

客戶介面: CustomerService

 

/**

* 客戶的業務層介面

*/

public interface ICustomerService {

/**

* 儲存客戶

* @param customer

*/

void saveCustomer();

}

 

客戶的實現類 CustomerServiceImpl:

/**

* 客戶的業務層實現類

*/

public class CustomerServiceImpl implements ICustomerService {

private ICustomerDao customerDao = new CustomerDaoImpl();// 此處有依賴關係

@Override

public void saveCustomer() {

customerDao.saveCustomer();

}

}

 

2.1.2  建立持久層介面和實現類

客戶的持久層介面:

public interface ICustomerDao {

/**

* 儲存客戶

*/

void saveCustomer();

}

 

 

 客戶的持久層實現類:

 

public class CustomerDaoImpl implements ICustomerDao {

@Override

public void saveCustomer() {

System.out.println("儲存了客戶");

}

}

 

 

2.2 基於XML的配置

2.2.1 環境搭建

2.2.1.1 第一步: 拷貝必備的jar包到工程的lib目錄

2.2.1.2 第二步:在類的根路徑下建立一個任意名稱的 xml  檔案 (不能是中文)

給配置檔案匯入約束:

<?xml version="1.0" encoding="UTF-8"?>

<!-- 匯入 schema

約束的位置在:

..\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html

檔案中。注意:要匯入 schema 約束

-->

<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">

</beans>

2.2.1.3  第三步:把資源交給 spring  來管理置 ,在配置檔案中配置 service  和 dao

<!-- 把資源交給 spring 來管理 -->

<bean id="customerDao" class="com.bdqn.dao.impl.CustomerDaoImpl"/>

<bean id="customerService" class="com.bdqn.service.impl.CustomerServiceImpl"/>

2.2.2  測試環境是否成功

2.2.2.1  獲取 spring  容器

/**

* 模擬一個表現層

*/

public class Client {

/**

* 獲取 spring 的容器,以及從容器中獲取 bean 物件

*

* ApplicationContext

* 它是一個介面,有兩個實現類。

* 分別是:

* ClassPathXmlApplicationContext:

* 它永遠都是從類的根路徑下載入配置檔案 推薦使用這種

* FileSystemXmlApplicationContext:

* 它是從磁碟路徑上載入配置檔案,配置檔案可以在磁碟的任意位置。

*/

public static void main(String[] args) {

//1.使用 ApplicationContext 介面,就是在獲取 spring 容器

ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");

//2.根據 bean 的 id 獲取物件

ICustomerService  customerService  =  (ICustomerService)

ac.getBean("customerService");

System.out.println(customerService);

ICustomerDao customerDao = (ICustomerDao) ac.getBean("customerDao");

System.out.println(customerDao);

}

}

問題:由於物件都交給 spring 管理了,這時如果我們把 service 實現了的這行程式碼:

private ICustomerDao customerDao = new CustomerDaoImpl();// 此處有依賴關係

改為

private ICustomerDao customerDao = null;

使用 service 物件呼叫 saveCustomer 方法會出現什麼問題呢?

執行結果:

空指標異常。

原因是 customerDao 物件沒有賦值。

如果在程式執行期間,spring  框架能幫我們給 customerDao  物件賦了值,那該多好。

帶著腦海裡的這個想法,繼續往下看。

2.2.2.2 Spring工廠類結構

BeanFactory 才是 Spring 容器中的頂層介面。ApplicationContext 是它的子介面。

BeanFactory 和 ApplicationContext 的區別:建立物件的時間點不一樣。

ApplicationContext:只要一讀取配置檔案,預設情況下就會建立物件。

BeanFactory:什麼時候物件使用什麼時候建立物件。

2.2.3 IOC 中 中 bean  標籤 和 管理物件細節

2.2.3.1 bean  標籤

作用:

用於配置物件讓 spring 來建立的。

預設情況下它呼叫的是類中的無參建構函式。如果沒有無參建構函式則不能建立成功。

屬性:

id :給物件在容器中提供一個唯一標識。用於獲取物件。

class :指定類的全限定類名。用於反射建立物件。預設情況下呼叫無參建構函式。

scope :指定物件的作用範圍。

* singleton :預設值,單例的.

* prototype :多例的.

* request  :WEB 專案中,Spring 建立一個 Bean 的物件,將物件存入到 request 域中.

* session  :WEB 專案中,Spring 建立一個 Bean 的物件,將物件存入到 session 域中.

init-method :指定類中的初始化方法名稱。

destroy-method :指定類中銷燬方法名稱。

2.2.3.2 bean  的作用範圍和生命週期

單例物件: scope="singleton"

一個應用只有一個物件的例項。它的作用範圍就是整個引用。

生命週期:

物件出生:當應用載入,建立容器時,物件就被建立了。

物件活著:只要容器在,物件一直活著。

物件死亡:當應用解除安裝,銷燬容器時,物件就被銷燬了。

多例物件: scope="prototype"

每次訪問物件時,都會重新建立物件例項。

生命週期:

物件出生:當使用物件時,建立新的物件例項。

物件活著:只要物件在使用中,就一直活著。

物件死亡:當物件長時間不用時,被 java 的垃圾回收器回收了。

2.2.4 spring  的依賴注入

2.2.4.1  依賴注入的概念

它是 spring 框架核心 ioc 的具體實現方式。簡單的說,就是坐等框架把物件傳入,而不用我們自己去獲取.

2.2.4.2 建構函式注入

顧名思義,就是使用類中的建構函式,給成員變數賦值。注意,賦值的操作不是我們自己做的,而是通過配置的方式,讓 spring 框架來為我們注入。具體程式碼如下:

public class CustomerServiceImpl implements ICustomerService {

private String name;

private Integer age;

private Date birthday;

public CustomerServiceImpl(String name, Integer age, Date birthday) {

this.name = name;

this.age = age;

this.birthday = birthday;

}

@Override

public void saveCustomer() {

System.out.println(name+","+age+","+birthday);

}

}

<!-- 使用建構函式的方式,給 service 中的屬性傳值

要求:

類中需要提供一個對應引數列表的建構函式。

涉及的標籤:

constructor-arg

屬性:

index:指定引數在建構函式引數列表的索引位置

type:指定引數在建構函式中的資料型別

name:指定引數在建構函式中的名稱 用這個找給誰賦值

=======上面三個都是找給誰賦值,下面兩個指的是賦什麼值的==============

value:它能賦的值是基本資料型別和 String 型別

ref:它能賦的值是其他 bean 型別,也就是說,必須得是在配置檔案中配置過的 bean

-->

<bean id="customerService" class="com.bdqn.service.impl.CustomerServiceImpl">

<constructor-arg name="name" value=" 張三 "></constructor-arg>

<constructor-arg name="age" value="18"></constructor-arg>

<constructor-arg name="birthday" ref="now"></constructor-arg>

</bean>

<bean id="now" class="java.util.Date"></bean>

 

2.2.4.3 Set方法注入(重點)

顧名思義,就是在類中提供需要注入成員的 set 方法。具體程式碼如下:

public class CustomerServiceImpl implements ICustomerService {

private String name;

private Integer age;

private Date birthday;

public void setName(String name) {

this.name = name;

}

public void setAge(Integer age) {

this.age = age;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

@Override

public void saveCustomer() {

System.out.println(name+","+age+","+birthday);

}

}

<!-- 通過配置檔案給 bean 中的屬性傳值:使用 set 方法的方式

涉及的標籤:

property

屬性:

name:找的是類中 set 方法後面的部分

ref:給屬性賦值是其他 bean 型別的

value:給屬性賦值是基本資料型別和 string 型別的

實際開發中,此種方式用的較多。

-->

<bean id="customerService" class="com.bdqn.service.impl.CustomerServiceImpl">

<property name="name" value="test"></property>

<property name="age" value="21"></property>

<property name="birthday" ref="now"></property>

</bean>

<bean id="now" class="java.util.Date"></bean>

     

Spring  第 二 天

第1 章 基於註解的 IOC  配置

1.1  寫在最前

學習基於註解的 IoC 配置,大家腦海裡首先得有一個認知,即註解配置和 xml 配置要實現的功能都是一樣的,都是要降低程式間的耦合。只是配置的形式不一樣。關於實際的開發中到底使用 xml 還是註解,每家公司有著不同的使用習慣。所以這兩種配置方式我們都需要掌握。

1.2  環境搭建

1.2.1  第一步:拷貝必備 jar 包到工程的 lib 目錄。

注意:在基於註解的配置中,我們還要多拷貝一個 aop 的 jar 包。如下圖:

1.2.2  第二步:在類的根路徑下建立一個任意名稱的 xml  檔案 (不能是中文)

基於註解整合時,匯入約束時需要多匯入一個 context 名稱空間下的約束.

 

給配置檔案匯入 context 約束:

 

 

<?xml version="1.0" encoding="UTF-8"?>

<?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.xsd

   http://www.springframework.org/schema/context

   http://www.springframework.org/schema/beans/spring-context.xsd">

  

</beans>

 

1.2.3 使用@Component 註解配置管理的資源

@Component(value="customerServie")

public class CustomerServiceImpl implements CustomerService {

   @Override

   public void saveCustomer(Customer customer) {

      System.out.println("執行了儲存客戶!");

   }

}

1.2.4  第四步在 spring  的配置檔案中開啟 spring  對註解 ioc 的支援

<!-- 告知spring框架在,讀取配置檔案,建立容器時,掃描註解,依據註解建立物件,並存入容器中 -->

<context:component-scan base-package="com.bdqn"></context:component-scan>

1.3 常用註解

1.3.1  用於建立物件的

相當於:<bean id="" class="">

1.3.1.1 @Component

作用:

把資源讓 spring 來管理。相當於在 xml 中配置一個 bean。

屬性:

value:指定 bean 的 id。如果不指定 value 屬性,預設 bean 的 id 是當前類的類名。首

字母小寫。

1.3.1.2 @Controller @Service @Repository

他們三個註解都是針對一個的衍生註解,他們的作用及屬性都是一模一樣的。

他們只不過是提供了更加明確的語義化。

@Controller :一般用於表現層的註解。

@Service :一般用於業務層的註解。

@Repository :一般用於持久層的註解。

細節:如果註解中有且只有一個屬性 要賦值時是 ,且名稱是 value ,value可以省略 。

1.3.2  用於注入資料的

相當於:<property name="" ref=""> <property name="" value="">

1.3.2.1 @Autowired

作用:

自動按照型別注入。當使用註解注入屬性時,set 方法可以省略。它只能注入其他 bean

型別。當有多個型別匹配時,使用要注入的物件變數名稱作為 bean 的 id,在 spring 容器查詢,找到了也可以注入成功。找不到就報錯。

1.3.2.2 @Qualifier(不經常使用)

作用:

在自動按照型別注入的基礎之上,再按照 Bean 的 id 注入。它在給欄位注入時不能獨

立使用,必須和@Autowire 一起使用;但是給方法引數注入時,可以獨立使用。

屬性:

value:指定 bean 的 id。

1.3.2.3 @Resource

作用:

直接按照 Bean 的 id 注入。它也只能注入其他 bean 型別。

屬性:

name:指定 bean 的 id。

1.3.2.4 @Value

作用:

注入基本資料型別和 String 型別資料的

屬性:

value:用於指定值

1.3.3  用於改變作用範圍的:

相當於:<bean id="" class="" scope="">

1.3.3.1 @Scope

作用:

指定 bean 的作用範圍。

屬性:value:指定範圍的值。

取值:singleton prototype request session

1.3.4  和生命週期相關的:( 瞭解)

相當於:<bean id="" class="" init-method="" destroy-method="" />

1.3.4.1 @PostConstruct

作用:

用於指定初始化方法。

1.3.4.2 @PreDestroy

作用:

用於指定銷燬方法。

1.3.5  關於註解和 XML  的選擇問題

註解的優勢:

配置簡單,維護方便(我們找到類,就相當於找到了對應的配置)。

XML  的優勢:

修改時,不用改原始碼。不涉及重新編譯和部署

1.4  spring  管理物件細節

基於註解的 spring IoC 配置中,bean 物件的特點和基於 XML 配置是一模一樣的。

寫到此處,基於註解的 IoC 配置已經完成,但是大家都發現了一個問題:我們依然離不開 spring的 xml 配置檔案,那麼能不能不寫這個 bean.xml,所有配置都用註解來實現呢?

答案是肯定的,請看下一章節。

1.5  spring  的純註解配置

建立物件的註解:
@Component
@Controller(用於web層)
@Service(用於service)
@Repository(用於dao)
 主配置檔案包掃描:
 <context:component-scan >
依賴注入:
@Autowired(自動按照型別注入)
@Qualifier(和@Autowired配合使用用於指定具體型別 value屬性指定)
@Resource:jdk    name屬性 用於指定具體型別
如果只有一個實現類: autowire和resource註解可以互換 

1.5.1  待改造的問題

我們發現,之所以我們現在離不開 xml 配置檔案,是因為我們有一句很關鍵的配置:

<!-- 告知spring框架在,讀取配置檔案,建立容器時,掃描註解,依據註解建立物件,並存入容器中 -->

<context:component-scan base-package="cn.bdqn"></context:component-scan>

如果他要也能用註解配置,那麼我們就可以脫離 xml 檔案了。

1.5.2 使用註解配置要掃描的包

專案結構圖:

在此圖中,我們已經一點也看不到 xml 的身影了。那麼,那句關鍵的配置跑哪去了呢?

在一個新的類上:用這個類代替配置檔案.

配置類程式碼:

@Configuration //標明該類是一個配置類

@ComponentScan(basePackages= {"com.bdqn"})//配置掃描的包

public class SpringConfiguration {

}

測試類程式碼:

@Test

   public void testConfig() {

//1.獲取容器:由於我們已經沒有了 xml 檔案,所以再用讀取 xml 方式就不能用了。

//這時需要指定載入哪個類上的註解

      ApplicationContext aContext=new AnnotationConfigApplicationContext(SpringConfiguration.class);

      //從容器中獲得物件

      CustomerService customerService = (CustomerService) aContext.getBean("customerServie");

      Customer customer=new Customer();

      customer.setCustName("李斯");

      customer.setCustSource("網際網路");

      //呼叫物件的儲存使用者的方法

      customerService.saveCustomer(customer);

   }

 

1.5.3  新註解說明

1.5.3.1 @Configuration

作用:

用於指定當前類是一個配置類,會從該類上載入註解。讀取該類上@ ComponentScan 註解

初始化 spring 容器。

1.5.3.2 @ComponentScan

作用:

用於指定 spring 在初始化容器時要掃描的包。

屬性:

basePackages :用於指定要掃描的包。和該註解中的 value 屬性作用一樣。

1.5.3.3 @Bean

作用:把方法的返回值放入到Spring容器中

該註解只能寫在方法上,表明使用此方法建立一個物件,並且交給 spring 管理。

屬性:name :給當前@Bean 註解的方法建立的物件指定一個名稱(即 bean 的 id)。

配置類程式碼:

@Component

public class JdbcConfig {

   /**

   把方法的返回值放入Spring容器  name屬性用於指定物件的名字 

   相當於 <bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource"></bean>

   */

   @Bean(name="ds")

   public DataSource getDs() throws Exception {

      //建立一個數據源

      ComboPooledDataSource dataSource=new ComboPooledDataSource();

      //設定資料來源連線資料庫的四要素

      dataSource.setDriverClass("com.mysql.jdbc.Driver");

      dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");

      dataSource.setUser("root");

      dataSource.setPassword("root");

      //返回資料來源

      return dataSource;

   }

}

測試程式碼:

@Test

   public void testBean() {

      //根據配置類獲得容器

      ApplicationContext aContext=new AnnotationConfigApplicationContext(SpringConfiguration.class);

      //從容器中獲得資料來源

      DataSource dSource=(DataSource) aContext.getBean("ds");

      //建立QueryRunner物件

      QueryRunner runner=new QueryRunner(dSource);

      //實行插入資料語句

      try {

         runner.update("insert into account (username,money) values('Monica',500000)");

      } catch (SQLException e) {

         e.printStackTrace();

      }

   }

1.5.3.4 @Import

作用:

用於匯入其他配置類

屬性:

value[] :用於指定其他配置類的位元組碼。

示例程式碼:這樣就不需要再向容器中放入JdbcConfig類,@Component註解省略

直接使用@Important註解載入配置類

@Configuration //標明該類是一個配置類

@ComponentScan("com.bdqn")//配置掃描的包

@Import(JdbcConfig.class)//用於匯入其它配置類

public class SpringConfiguration {

}

1.5.3.5 @PropertySource

作用:用於載入.properties 檔案中的配置

屬性:

value[] :用於指定 properties 檔案位置。如果是在類路徑下,需要寫上 classpath:

public class JdbcConfig {

   @Value("${jdbc.driver}")

   private String driver;

   @Value("${jdbc.url}")

   private String url;

   @Value("${jdbc.username}")

   private String username;

   @Value("${jdbc.password}")

   private String password;

   @Bean(name="ds")

   public DataSource getDs() throws Exception {

      //建立一個數據源

      ComboPooledDataSource dataSource=new ComboPooledDataSource();

      //設定資料來源連線資料庫的四要素

      dataSource.setDriverClass(driver);

      dataSource.setJdbcUrl(url);

      dataSource.setUser(username);

      dataSource.setPassword(password);

      //返回資料來源

      return dataSource;

   }

注意4.3以前版本需要提供佔位符類:

我們目前上課使用的版本是 4.2.4, spring4.3  以前都需要提供一個佔位符配置器:

PropertySourcesPlaceholderConfigurer

而在 spring4.3  以後,則不需要提供。

提供 的方式如下:(在 SpringConfiguration JdbcConfig 配置均可

4.2版本的配置

@Configuration //標明該類是一個配置類

@ComponentScan("com.bdqn")//配置掃描的包

@Import(JdbcConfig.class)//用於匯入其它配置類

@PropertySource("classpath:/com/bdqn/config/jdbc.properties")

//匯入properties配置檔案 value屬性用於指定配置檔案的位置

public class SpringConfiguration {

   @Bean(name="pspc")

   public static PropertySourcesPlaceholderConfigurer createPSPC() {

      return new PropertySourcesPlaceholderConfigurer();

   }

}

 

1.5.3.6 @Qualifier的第二種使用方法

1.第一種方式  和@Autowire一起配合起來使用,用於指定固定一個物件的配置.

2.用於向方法引數注入Spring容器中物件.

示例程式碼:

@Bean(name="ds")

   public DataSource getDs() throws Exception {

      //建立一個數據源

      ComboPooledDataSource dataSource=new ComboPooledDataSource();

      //設定資料來源連線資料庫的四要素

      dataSource.setDriverClass(driver);

      dataSource.setJdbcUrl(url);

      dataSource.setUser(username);

      dataSource.setPassword(password);

      //返回資料來源

      return dataSource;

   }

   /**

    * @Qualifier("ds") 直接使用容器中的ds 向形參賦值

    */

   @Bean(name="qr")

   public QueryRunner getRunner(@Qualifier("ds")DataSource ds) {

      return new QueryRunner(ds);

   }

測試程式碼:

   @Test

   public void testBean() {

      //根據配置類獲得容器

      ApplicationContext aContext=new AnnotationConfigApplicationContext(SpringConfiguration.class);

      //建立QueryRunner物件

      QueryRunner runner=(QueryRunner) aContext.getBean("qr");

      //實行插入資料語句

      try {

         runner.update("insert into account (username,money) values('runner',100)");

      } catch (SQLException e) {

         e.printStackTrace();

      }

   }

第2章Spring整合Junit

2.1  準備測試環境

2.1.1 建立業務層介面和實現類

業務層介面:

public interface CustomerService {

   //儲存使用者的方法

   public void saveCustomer(Customer customer);

   //查詢所有使用者方法

   public List<Customer> getCustomers();

}

業務層實現類:

@Component("customerServie")

public class CustomerServiceImpl implements CustomerService {

   private CustomerDao customerDao;

   //提供set方法用於注入customerDao物件