大約20年前,程序員們使用「企業級Java Bean」(EJB)開發企業應用,須要配置複雜的XML。
在二十世紀初期,新興Java技術——Spring,橫空出世。使用極簡XML和POJO(普通Java對象),結合EJB的替代品(如Hibernate),Spring在企業級Java開發上佔據了絕對領先地位。
可是,隨着Spring的不斷髮展,當初的XML配置逐漸變得複雜龐大,成了累贅,遭衆多程序員「詬病」。後來,Spring推出了JavaConfig項目,使用聲明式的註解,大量減小了顯式的XML配置。
然而,問題到這裏,並無結束。html
J2EE使用多層的分佈式應用模型,以下圖所示:java
應用邏輯按功能劃分爲組件,各個應用組件根據他們所在的層分佈在不一樣的機器上。事實上,sun設計J2EE的初衷正是爲了解決兩層模式(client/server)的弊端,在傳統模式中,客戶端擔當了過多的角色而顯得臃腫。
J2EE平臺由一整套服務(Services)、應用程序接口(APIs)和協議構成,它對開發基於Web的多層應用提供了功能支持。
以下是對J2EE中的13種技術規範進行簡單的描述[3]:python
J2EE提供了"編寫一次、隨處運行"的特性、方便存取數據庫的JDBC API、CORBA技術以及可以在Internet應用中保護數據的安全模式等等,同時還提供了對 EJB(Enterprise JavaBeans)、Java Servlets API、JSP(Java Server Pages)以及XML(標準通用標記語言的子集)技術的全面支持。git
爲了解決這些問題,出現了Struts框架,它是一個完美的MVC實現,它有一箇中央控制類(一個Servlet),針對不一樣的業務,咱們須要一個Action類負責頁面跳轉和後臺邏輯運算,一個或幾個JSP頁面負責數據的輸入和輸出顯示,還有一個Form類負責傳遞Action和JSP中間的數據。JSP中可使用Struts框架提供的一組標籤,就像使用HTML標籤同樣簡單,可是能夠完成很是複雜的邏輯。今後JSP頁面中不須要出現一行<%%>包圍的Java代碼了。
但是全部的運算邏輯都放在Struts的Action裏將使得Action類複用度低和邏輯混亂,因此一般人們會把整個Web應用程序分爲三層,Struts負責顯示層,它調用業務層完成運算邏輯,業務層再調用持久層完成數據庫的讀寫。
使用JDBC鏈接來讀寫數據庫,咱們最多見的就是打開數據庫鏈接、使用複雜的SQL語句進行讀寫、關閉鏈接,得到的數據又須要轉換或封裝後往外傳,這是一個很是煩瑣的過程。程序員
這時出現了Hibernate框架。它對JDBC提供了封裝。Hibernate的O/R Mapping實現了POJO 和數據庫表之間的映射,以及SQL的自動生成和執行。
Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了很是輕量級的對象封裝,它將POJO與數據庫表創建映射關係,是一個全自動的orm框架,hibernate能夠自動生成SQL語句,自動執行,使得Java程序員能夠爲所欲爲的使用對象編程思惟來操縱數據庫。 Hibernate能夠應用在任何使用JDBC的場合,既能夠在Java的客戶端程序使用,也能夠在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate能夠在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。[8]
如今咱們有三個層了,但是每層之間的調用是怎樣的呢?好比顯示層的Struts須要調用一個業務類,就須要new一個業務類出來,而後使用;業務層須要調用持久層的類,也須要new一個持久層類出來用。經過這種new的方式互相調用就是軟件開發中最糟糕設計的體現。簡單的說,就是調用者依賴被調用者,它們之間造成了強耦合,若是我想在其餘地方複用某個類,則這個類依賴的其餘類也須要包含。程序就變得很混亂,每一個類互相依賴互相調用,複用度極低。若是一個類作了修改,則依賴它的不少類都會受到牽連。 爲此,出現了Spring框架。github
MyBatis是另一個普遍使用的ORM框架。本來是Apache的一個開源項目iBatis, 後更名爲MyBatis 。MyBatis的核心在於管理 POJO 與 SQL 之間的映射關係。MyBatis 使用簡單的 XML或註解用於配置和原始映射,將接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。
Mybatis框架的架構以下圖:web
Spring框架至今已集成了20多個模塊。這些模塊主要被分以下圖所示的核心容器、數據訪問/集成,、Web、AOP(面向切面編程)、工具、消息和測試模塊[5]:
Spring總體架構
核心部分分爲4大塊,spring-core, spring-beans, spring-context, spring-expression. 其中core和bean是整個框架的核心,提供了基礎的DI和IoC功能。 Context創建在core和beans模塊之上,提供一種相似JNDI且以框架的方式來操做對象的方式。Context模塊從beans模塊繼承它的功能同時增長了國際化支持,如資源綁定等,同時,Context模塊也支持JavaEE功能,如EJB,JMX和基本的遠程調用。ApplicationContext接口是context模塊的焦點。expression是一種很強大的expression language,支持在運行時查詢和操做對象的屬性,咱們會在後面的文章中舉些例子來講明spring expression language的用法。
Aop模塊提供了面向切面編程的實現,和AspectJ集成。
Messaging是spring4新增長的模塊,包含了一部分主要的基於message的應用的實現。
Data access顧名思義,是spring對數據層提供的支持,是功能比較豐富的模塊。提供了包括JDBC,事物,ORM,JMS等一系列實現。
Web模塊主要提供面向web的一些實現,例如多文件上傳,servlet監聽器以及spring mvc方面的支持。
Test模塊主要是針對spring的各個模塊作各類各樣的測試,包括單元測試、集成測試等等。
通常代碼的操做對象是數據。元編程操做的對象是代碼。
元編程一言以蔽之,就是用代碼生成(操縱)代碼。在運行時建立和修改代碼而非編程時,這種程序叫作元程序。而編寫這種程序就叫作元編程。元編程是用代碼在編譯期或運行期生成/改變代碼。元編程是現實世界的抽象的利器。
元編程技術在多種編程語言中均可以使用,但更多的仍是被應用於動態語言中,由於動態語言提供了更多的在運行時將代碼視爲數據進行操縱的能力。
Java 5中提供了Annotations,它是Java的metadata。Java應用中的元數據在早期Java版本中,通常使用屬性文件、XML,後來註解出現了,就都用註解了。
Java經過反射機制實現元編程。反射是促進元編程的一種頗有價值的語言特性。
常見的開發語言均能作到元編程,Lisp就不用多說了,C的Marco,C++的Template,Java的Annotation,C#的Attribute、Reflection、CodeDom和IL Emitter,各類腳本語言(如js、python)的eval,甚至連Unix/Linux的shell腳本也能。
元編程常見的應用場景不少,擴展語法、開發DSL、生成代碼、根據特定場景自動選擇代碼優化、解決一些正交的架構設計問題、AOP等等。
元編程,是對語言自身再向上一層抽象。
Spring IOC有一個很是核心的概念——Bean。由Spring容器來負責對Bean的實例化,裝配和管理。XML是用來描述Bean最爲流行的配置方式。Spring能夠從XML配置文件中讀取任何類型的元數據並自動轉換成相應的Java代碼。Spring改變了java的編程模式。
隨着Spring的日益發展,愈來愈多的人對Spring提出了批評。「Spring項目大量的爛用XML」就是最爲嚴勵的一個批評。因爲Spring會把幾乎全部的業務類都以Bean的形式配置在XML文件中,形成了大量的XML文件。使用XML來配置Bean失去了編譯時的類型安全檢查。大量的XML配置使得整個項目變得更加複雜。Rod Johnson也注意到了這個很是嚴重的問題。
當隨着Java EE 5.0的發佈,其中引入了一個很是重要的特性——Annotations(註解)。註解是源代碼的標籤,這些標籤能夠在源代碼層進行處理或經過編譯器把它熔入到class文件中。在Java EE 5之後的版本中,註釋成爲了一個主要的配置選項。Spring使用註釋來描述Bean的配置與採用XML相比,因類註釋是在一個類源代碼中,能夠得到類型安全檢查的好處。能夠良好的支持重構。
JavaConfig就是使用註釋來描述Bean配置的組件。JavaConfig 是Spring的一個子項目(詳細瞭解可參考:http://docs.spring.io/spring-javaconfig/docs/).
後來,當@Annotation出現了,大部分技術、框架就紛紛放棄了XML配置文件,改成使用Annotation來管理配置信息。
Spring有2種經常使用的配置方式:
Spring的XML配置方式是使用被Spring命名空間的所支持的一系列的XML標籤來實現的。Spring有如下主要的命名空間:context、beans、jdbc、tx、aop、mvc等。
使用XML來配置Bean所能實現的功能,經過JavaConfig一樣能夠很好的實現。以前咱們都是在xml文件中定義bean的,好比:
<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-3.0.xsd">
<bean id="helloBean" class="com.hello.impl.HelloWorldImpl">
</beans>
其實咱們可使用註解來完成這些事情,例以下面的代碼,完成的功能和上面的xml配置的功能是同樣的:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.hello.HelloWorld; import com.hello.impl.HelloWorldImpl; @Configuration public class AppConfig { @Bean(name="helloBean") public HelloWorld helloWorld() { return new HelloWorldImpl(); } }
使用@Bean註解,來標識此方法構造出一個由Spring容器管理的bean。Spring對Java配置的支持是由@Configuration註解和@Bean註解來實現的。由@Bean註解的方法將會實例化、配置和初始化一個新對象,這個對象將由Spring的IoC容器來管理。@Bean聲明所起到的做用與<bean/> 元素相似。被@Configuration所註解的類則表示這個類的主要目的是做爲bean定義的資源。被@Configuration聲明的類能夠經過在同一個類的內部調用@bean方法來設置嵌入bean的依賴關係。
通常在一個大型工程項目中,若是將全部的bean都配置在一個xml文件中,那麼這個文件就會很是的大。因此通常會將一個大的xml配置文件分割爲好幾份。這樣方便管理,最後在總的那個xml文件中導入。好比:
1 <beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://www.springframework.org/schema/beans 4 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 5 6 <import resource="config/customer.xml"/> 7 <import resource="config/scheduler.xml"/> 8 9 </beans>
可是如今咱們也可使用JavaConfig來完成一樣的工做了:
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; @Configuration @Import({ CustomerConfig.class, SchedulerConfig.class }) public class AppConfig { }
@Configuration能夠被認爲是至關於XML的< bean / >元素。
Spring在2.5版本之後開始支持用註解的方式來配置依賴注入。能夠用註解的方式來替代XML方式的bean描述,能夠將bean描述轉移到組件類的內部,只須要在相關類上、方法上或者字段聲明上使用註解便可。使用JavaConfig的配置方式,一行XML代碼都不須要,什麼web.xml,Application-context.xml,Beans.xml,通通再見。
在 Spring XML中, 啓動註解注入bean,經過以下標籤實現:
<context:annotation-config/>
在 JavaConfig中, 等同於 @AnnotationDrivenConfig註解。
代碼示例:
@Configuration
@AnnotationDrivenConfig
public class Config { // may now use @Autowired to reference beans from other @Configuration classes, XML, etc }
使用@ComponentScan註解,等同於在 Spring XML中的
<context:component-scan/>
代碼示例:
package com.company.foo;
@Service
public class FooServiceImpl implements FooService { private final FooRepository fooRepository; @Autowired public FooService(FooRepository fooRepository) { this.fooRepository = fooRepository; } // ... } package com.company.foo; @Repository public class JdbcFooRepository implements FooRepository { private final DataSource dataSource; @Autowired public FooRepository(DataSource dataSource) { this.dataSource = dataSource; } // ... } @Configuration @ComponentScan("com.company") // search the com.company package for @Component classes @ImportXml("classpath:com/company/data-access-config.xml") // XML with DataSource bean public class Config { }
在配置類中使用上述的配置,咱們就能夠在代碼裏調用service方法了:
public class Main {
public static void main(String[] args) { JavaConfigApplicationContext ctx = new JavaConfigApplicationContext(Config.class); FooService fooService = ctx.getBean(FooService.class); fooService.doStuff(); } }
Spring框架項目的出發點是爲了解決被其餘框架所忽略的部分。在J2EE各個具體領域,都有不少出色的解決方案,web框架持久化方案,遠程調用工具等等,然而將這些工具整合成一個全面的架構,卻困難重重,甚至成爲一種負擔。spring提供了一個完整的解決方案,將各類專用框架整合成一個連貫的總體的架構。
Spring誕生之初,就是爲了解決當初EJB的重量級複雜編程問題。Spring經過輕量級的架構,使用IOC(DI)和AOP,用POJO實現了EJB的功能。但是,Spring使人頭疼的繁雜的配置,讓開發者陷入了另外一個深淵(世間萬物,每每如此)。一開始,Spring使用大量xml配置。Spring 2.5引入了基於註解的組件掃描,消除了大量針對應用自身的組件的xml配置。Spring 3.0 有了Java Config解決方案,能夠替代xml。可是,仍是有使用不少Spring的特性,諸如事務管理,SpringMVC,以及集成第三方框架的時候(好比模板引擎:velocity, freemarker, thymeleaf),仍是須要大量的顯式配置。配置Servlet和Filter等一樣須要在web.xml裏面配置。
對了,還有運行調試的時候,須要配置web容器等大量手工勞動。
這些配置,耗去了程序員們的大量的精力和時間,使得生產效率大減折扣。程序員們的大腦不得不在編寫業務邏輯代碼跟xml配置之間來回切換。
在後面的章節中,咱們將看到Spring Boot對程序員更加簡易地使用Spring框架上面所帶來的巨大變化,以及對Spring生態體系,各類技術框架的的整合集成。
Spring Boot,簡單講就是犧牲項目的自由度來減小配置的複雜度(「契約式編程」思想,SpringBoot自動配置方案的指導思想)。約定一套規則,把這些框架都自動配置集成好,從而達到「開箱即用」。同時,也支持自由配置。這就是一個很是好的方案了。
Java Web開發涉及的技術比較繁雜,涉及到不少開發框架和工具(Java, Scala, Kotlin, Clojure,Groovy, Grails,Gradle, Maven, JDBC,Mysql, oracle, mongodb, Tomcat,Jetty,Spring,Struts,Hibernate,Mybatis,JPA,JSP,velocity,freemarker,thymeleaf ,Redis,... ),並且它們各有所長,並非一個完善的體系。這對程序員能進行Jave Web開發,帶來了必定的技術門檻和學習成本。
有沒有一個像「航空母艦(Aircraft Carrier)」式的威力強大的武器,能夠整合這一切呢?答案就是:Spring Boot。
SpringBoot讓建立獨立的,生產環境的基於Spring的應用更加快捷簡易。 大部分Spring Boot Application只要一些極簡的配置,便可「一鍵運行」。
SpringBoot的特性以下[1]:
Spring因爲其繁瑣的配置,一度被人認爲「配置地獄」,各類XML、Annotation配置,讓人眼花繚亂,並且若是出錯了也很難找出緣由。而Spring Boot更多的是採用Java Config的方式,對Spring進行配置。
咱們企業級軟件的目標是提供穩定健壯的服務,以實現其商業價值。爲了知足這些需求,服務開發者須要可以快速構建和迭代新的應用,同時應用的架構是可擴展的,便攜式的,富彈性的,能夠進行頻繁的更新。SpringBoot正式爲此而誕生[2]。
SpringBoot是伴隨着Spring4.0誕生的;
從字面理解,Boot是引導的意思,所以SpringBoot幫助開發者快速搭建Spring框架;SpringBoot幫助開發者快速啓動一個Web容器;SpringBoot繼承了原有Spring框架的優秀基因;SpringBoot使得基於Spring的開發過程更加簡易。
Change is inevitable, that's the only constant. Become the Future You Imagine (Rob Mee, Pivotal CEO)[3]
Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員再也不須要定義樣板化的配置。經過這種方式,Boot致力於在蓬勃發展的快速應用開發領域(rapid application development)成爲領導者。
多年以來,Spring IO平臺飽受非議的一點就是大量的XML配置以及複雜的依賴管理。在去年的SpringOne 2GX會議上,Pivotal的CTO Adrian Colyer迴應了這些批評,而且特別提到該平臺未來的目標之一就是實現免XML配置的開發體驗。Boot所實現的功能超出了這個任務的描述,開發人員不只再也不須要編寫XML,並且在一些場景中甚至不須要編寫繁瑣的import語句。
然而,Spring Boot並非要成爲Spring IO平臺裏面衆多「Foundation」層項目的替代者。Spring Boot的目標不在於爲已解決的問題域提供新的解決方案,而是爲平臺帶來另外一種開發體驗,從而簡化對這些已有技術的使用。對於已經熟悉Spring生態系統的開發人員來講,Boot是一個很理想的選擇,不過對於採用Spring技術的新人來講,Boot提供一種更簡潔的方式來使用這些技術。
做爲當前主流的企業框架Spring,它提供了一整套相關的頂級項目,能讓開發者快速的上手實現本身的應用。請看下圖「Spring航空母艦」:
目前來講spring主要集中於spring boot(用於開發微服務)和spring cloud相關框架的開發。spring cloud子項目包括:
SpringBoot項目源碼:https://github.com/spring-projects/spring-boot
SpringBoot學習示例:https://github.com/netgloo/spring-boot-samples
版本歷史參考:https://github.com/spring-projects/spring-boot/releases
正由於Spring Boot是與Spring一脈相承的,因此對於廣大的Java開發者而言,對於Spring的學習成本幾乎爲零。
在實踐Spring Boot時學習重點,或者說思惟方式改變的重點在於:
1)對於REST的理解,這一點尤其重要,須要從設計、開發多個角色達成共識,不少時候都是對於HTTP 1.1協議以及REST的精髓不理解,致使REST被「盲用」而產生一些很差的效果。
2)對於YAML的理解和對於JavaConfig的理解,這兩點相對較爲簡單,本質上是簡化了xml文件,並提供等價的配置表述能力。
1.http://projects.spring.io/spring-boot/
2.https://pivotal.io/spring-app-framework#buildanything
3.https://pivotal.io/
4.http://www.infoq.com/cn/articles/microframeworks1-spring-boot
5.http://blog.csdn.net/zeb_perfect/article/details/51945350
6.http://projects.spring.io/
7.SpringBoot官網文檔:http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/