【一頭扎進Spring】 01 | 從 HelloWorld 開始看Spring
- Spring 是一個開源框架.
- Spring 為簡化企業級應用開發而生. 使用 Spring 可以使簡單的 JavaBean 實現以前只有 EJB 才能實現的功能.
- Spring 是一個 IOC(DI) 和 AOP 容器框架.
開發環境 - 開發工具: IDEA
- JDK 8.0
- Spring 4.0
Spring 的簡單介紹
具體描述 Spring:
- 輕量級:Spring 是非侵入性的 - 基於 Spring 開發的應用中的物件可以不依賴於 Spring 的 API
- 依賴注入(DI --- dependency injection、IOC)
- 面向切面程式設計(AOP --- aspect oriented programming)
- 容器: Spring 是一個容器, 因為它包含並且管理應用物件的生命週期
- 框架: Spring 實現了使用簡單的元件配置組合成一個複雜的應用. 在 Spring 中可以使用 XML 和 Java 註解組合這些物件
- 一站式:在 IOC 和 AOP 的基礎上可以整合各種企業應用的開源框架和優秀的第三方類庫 (實際上 Spring 自身也提供了展現層的 SpringMVC 和 持久層的 Spring JDBC)
Spring 模組
核心容器(Core Container) 包括Core、Beans、Context、EL模組
- Core和Beans模組提供了Spring最基礎的功能,提供IoC和依賴注入特性。這裡的基礎概念是BeanFactory,它提供對Factory模式的經典實現來消除對程式性單例模式的需要,並真正地允許你從程式邏輯中分離出依賴關係和配置。
- Context模組基於Core和Beans來構建,它提供了用一種框架風格的方式來訪問物件,有些像JNDI登錄檔。Context封裝包繼承了beans包的功能,還增加了國際化(I18N),事件傳播,資源裝載,以及透明建立上下文,例如通過servlet容器,以及對大量JavaEE特性的支援,如EJB、JMX。核心介面是ApplicationContext。
- Expression Language,表示式語言模組,提供了在執行期間查詢和操作物件圖的強大能力。支援訪問和修改屬性值,方法呼叫,支援訪問及修改陣列、容器和索引器,命名變數,支援算數和邏輯運算,支援從Spring 容器獲取Bean,它也支援列表投影、選擇和一般的列表聚合等。
資料訪問/整合部分(Data Access/Integration)
- JDBC模組,提供對JDBC的抽象,它可消除冗長的JDBC編碼和解析資料庫廠商特有的錯誤程式碼。
- ORM模組,提供了常用的"物件/關係"對映APIs的整合層。 其中包括JPA、JDO、Hibernate 和 iBatis 。利用ORM封裝包,可以混合使用所有Spring提供的特性進行"物件/關係"對映,如簡單宣告性 事務管理 。
- OXM模組,提供一個支援Object和XML進行對映的抽象層,其中包括JAXB、Castor、XMLBeans、JiBX和XStream。
- JMS模組,提供一套"訊息生產者、消費者"模板用於更加簡單的使用JMS,JMS用於用於在兩個應用程式之間,或分散式系統中傳送訊息,進行非同步通訊。
- Transaction模組,支援程式通過簡單宣告性 事務管理,只要是Spring管理物件都能得到Spring管理事務的好處,即使是POJO,也可以為他們提供事務。
Web
- Web模組,提供了基礎的web功能。例如多檔案上傳、整合IoC容器、遠端過程訪問、以及Web Service支援,並提供一個RestTemplate類來提供方便的Restful services訪問
- Web-Servlet模組,提供了Web應用的Model-View-Controller(MVC)實現。Spring MVC框架提供了基於註解的請求資源注入、更簡單的資料繫結、資料驗證等及一套非常易用的JSP標籤,完全無縫與Spring其他技術協作。
- Web-Struts模組, 提供了對Struts整合的支援,這個功能在Spring3.0裡面已經不推薦了,建議你遷移應用到使用Struts2.0或Spring的MVC。
- Web-Portlet模組,提供了在Portlet環境下的MVC實現
AOP
- AOP模組,提供了符合AOP 聯盟規範的面向方面的程式設計實現,讓你可以定義如方法攔截器和切入點,從邏輯上講,可以減弱程式碼的功能耦合,清晰的被分離開。而且,利用原始碼級的元資料功能,還可以將各種行為資訊合併到你的程式碼中 。
- Aspects模組,提供了對AspectJ的整合。
- Instrumentation模組, 提供一些類級的工具支援和ClassLoader級的實現,可以在一些特定的應用伺服器中使用。
Test
- Test模組,提供對使用JUnit和TestNG來測試Spring元件的支援,它提供一致的ApplicationContexts並快取這些上下文,它還能提供一些mock物件,使得你可以獨立的測試程式碼。
HelloWorld
首先建立一個 Maven 工程(也可以使用IDEA裡面的那個 Spring . 這裡初學,就不建議使用那個了。同樣,建議建立 maven 工程,方便 Jar 包的管理);Maven工程大家就可以自己建立一個空白的 工程就行。
建立好我們的 Maven 工程後,我們需要配置好我們的 pom.xml 檔案,引入我們的開發包。
<dependencies>
<!-- Spring Core-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Beans-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Web-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring WebMvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Aop-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
我們的父工程的搭建好了之後,就開始建立我們的子工程。我這取名: spring-learning-quickstart.子工程是繼承父工程的,這樣我們就不用再次匯入我們的開發包了。
我們在 子工程中建立一個 bean , 取名 HelloWorld .
public class HelloWorld {
private String name ;
public void setName(String name) {
this.name = name;
}
public void sayHello(){
System.out.println("Hello " + name);
}
public HelloWorld() {
System.out.println("Constructor for HelloWorld");
}
}
然後,我們在建立一個主類 Main .
public class Main {
public static void main(String[] args) {
// 傳統做法( 這不是Spring 的做法)
HelloWorld helloWorld = new HelloWorld();
helloWorld.setName("Spring");
helloWorld.sayHello();
}
}
一執行,我們就可以看到控制檯出現了:
hello Spring
當然,這個不是 Spring 的方式。現在我們來看看 Spring 中怎麼去做。
Spring 實現
在Spring 中,我們需要通過配置去實現我們的這個 HelloWorld 的。首先,我們在 resource 中新建一個 XML 的檔案 。 我這就叫 applicationContext.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">
<!-- 配置Bean -->
<bean id="helloWorld" class="com.spring.bean.HelloWorld">
<property name="name" value="SunYang's Spring"></property>
</bean>
</beans>
這裡稍後在解釋。
然後我們在主類中,這麼來寫。
//1 建立 Spring 的 IOC 容器物件
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2 從IOC 容器中獲取 Bean 例項
HelloWorld hello = (HelloWorld)applicationContext.getBean("helloWorld");
//3 呼叫 sayHello()
hello.sayHello();
這樣我們的控制檯就出現:
hello SunYang's Spring
現在呢,先來看一下,Spring建立了這個容器的過程中幫我們做了什麼。我們在這個容器建立這邊打一個斷點。
然後程式執行到這以後,會自動跳到我們的 HelloWorld 類裡面,在看這個:
我們可以看到,這個時候Spring就已經把 SunYang's Spring 給了 name 了。
Spring 核心
兩個重點概念
- IOC: 控制反轉,與依賴注入 DI 一樣
- AOP: 面向切面程式設計
IOC
所謂控制反轉,其實是一個由主動轉被動的一個過程。舉個例子:
之前,我們沒有飲品店的時候,我們想喝果汁了,就是自己準備水果,然後自己榨果汁。這就是一個主動的創造一杯果汁的過程。但是,現在有飲品店了,我們想喝果汁了,我們就不在需要自己去榨一杯果汁,而是叫飲品店去榨一杯果汁,請注意,這裡我們並沒有創造一杯果汁,但是依然達到了我們要喝果汁的目的。這邊是控制反轉的思想。比如說:
我現在要喝 一個 大杯的三分糖的橙子汁。
/**
* 我們要喝的水果汁
* @param water 果汁加的水
* @param fruit 水果型別
* @param sugar 糖
* @return
*/
public static String juiceMix(String water , String fruit ,String sugar){
String juice = String.format("我要喝 %s 的 , %s 的 %s" , water ,sugar ,fruit ) ;
return juice ;
}
現在我們有了要喝的果汁,現在就是需要有人去做,相當於一個店家去做。
public class JuiceProduce {
private String water ;
private String fruit ;
private String sugar ;
public void setWater(String water) {
this.water = water;
System.out.println(this.water);
}
public void setFruit(String fruit) {
this.fruit = fruit;
}
public void setSugar(String sugar) {
this.sugar = sugar;
}
public JuiceProduce() {
System.out.println("Constructor for JuiceProduce");
}
public String juiceProduce(){
return Blende.juiceMix(this.water , this.fruit , this.sugar) ;
}
}
現在我們需要選擇那家店去喝這個果汁了,就是在 配置檔案裡面去配置一下。
<bean id="juiceProduce" class="com.spring.bean.JuiceProduce">
<property name="water" value="大杯" />
<property name="fruit" value="橙汁" />
<property name="sugar" value="三分糖"/>
</bean>
我們選擇這個名叫 juiceProduce 的店家來製造我們的果汁。最後的結果就是:
我要喝 大杯 的 , 三分糖 的 橙汁
在下一篇中,講一下這個關於 Bean 的配置問題