背景

  大约20年前,程序员们使用“企业级Java Bean”(EJB)开发企业应用,需要配置复杂的XML。
  在二十世纪初期,新兴Java技术——Spring,横空出世。使用极简XML和POJO(普通Java对象),结合EJB的替代品(如Hibernate),Spring在企业级Java开发上占据了绝对领先地位。
  但是,随着Spring的不断发展,当初的XML配置逐渐变得复杂庞大,成了累赘,遭众多程序员“诟病”。后来,Spring推出了JavaConfig项目,使用声明式的注解,大量减少了显式的XML配置。
  然而,问题到这里,并没有结束。

一、J2EE(Java 2 Platform Enterprise Edition)简介

  • javaee知识结构图

  

  • J2EE 的四层模型

J2EE使用多层的分布式应用模型,如下图所示:

  应用逻辑按功能划分为组件,各个应用组件根据他们所在的层分布在不同的机器上。事实上,sun设计J2EE的初衷正是为了解决两层模式(client/server)的弊端,在传统模式中,客户端担当了过多的角色而显得臃肿。
  J2EE平台由一整套服务(Services)、应用程序接口(APIs)和协议构成,它对开发基于Web的多层应用提供了功能支持。
  如下是对J2EE中的13种技术规范进行简单的描述[3]:

  • JDBC(Java Database Connectivity): JDBC API为访问不同的数据库提供了一种统一的途径,象ODBC一样,JDBC对开发者屏蔽了一些细节问题,另外,JDCB对数据库的访问也具有平台无关性。
  • JNDI(Java Name and Directory Interface): JNDI API被用于执行名字和目录服务。它提供了一致的模型来存取和操作企业级的资源如DNS和LDAP,本地文件系统,或应用服务器中的对象。
  • EJB(Enterprise JavaBean): J2EE技术之所以赢得某体广泛重视的原因之一就是EJB。它们提供了一个框架来开发和实施分布式商务逻辑,由此很显著地简化了具有可伸缩性和高度复杂的企业级应用的开发。EJB规范定义了EJB组件在何时如何与它们的容器进行交互作用。容器负责提供公用的服务,例如目录服务、事务管理、安全性、资源缓冲池以及容错性。但这里值得注意的是,EJB并不是实现J2EE的唯一途径。正是由于J2EE的开放性,使得有的厂商能够以一种和EJB平行的方式来达到同样的目的。
  • RMI(Remote Method Invoke): 正如其名字所表示的那样,RMI协议调用远程对象上方法。它使用了序列化方式在客户端和服务器端传递数据。RMI是一种被EJB使用的更底层的协议。
  • Java IDL/CORBA: 在Java IDL的支持下,开发人员可以将Java和CORBA集成在一起。 他们可以创建Java对象并使之可在CORBA ORB中展开, 或者他们还可以创建Java类并作为和其它ORB一起展开的CORBA对象的客户。后一种方法提供了另外一种途径,通过它Java可以被用于将你的新的应用和旧的系统相集成。
  • JSP(Java Server Pages): JSP页面由HTML代码和嵌入其中的Java代码所组成。服务器在页面被客户端所请求以后对这些Java代码进行处理,然后将生成的HTML页面返回给客户端的浏览器。
  • Java Servlet: Servlet是一种小型的Java程序,它扩展了Web服务器的功能。作为一种服务器端的应用,当被请求时开始执行,这和CGI Perl脚本很相似。Servlet提供的功能大多与JSP类似,不过实现的方式不同。JSP通常是大多数HTML代码中嵌入少量的Java代码,而servlets全部由Java写成并且生成HTML。
  • XML(Extensible Markup Language): XML是一种可以用来定义其它标记语言的语言。它被用来在不同的商务过程中共享数据。XML的发展和Java是相互独立的,但是,它和Java具有的相同目标正是平台独立性。通过将Java和XML的组合,您可以得到一个完美的具有平台独立性的解决方案。
  • JMS(Java Message Service): MS是用于和面向消息的中间件相互通信的应用程序接口(API)。它既支持点对点的域,有支持发布/订阅(publish/subscribe)类型的域,并且提供对下列类型的支持:经认可的消息传递,事务型消息的传递,一致性消息和具有持久性的订阅者支持。JMS还提供了另一种方式来对您的应用与旧的后台系统相集成。
  • JTA(Java Transaction Architecture): JTA定义了一种标准的API,应用系统由此可以访问各种事务监控。
  • JTS(Java Transaction Service): JTS是CORBA OTS事务监控的基本的实现。JTS规定了事务管理器的实现方式。该事务管理器是在高层支持Java
  • Transaction API (JTA)规范,并且在较底层实现OMG OTS specification的Java映像。JTS事务管理器为应用服务器、资源管理器、独立的应用以及通信资源管理器提供了事务服务。
  • JavaMail: JavaMail是用于存取邮件服务器的API,它提供了一套邮件服务器的抽象类。不仅支持SMTP服务器,也支持IMAP服务器。
  • JTA(JavaBeans Activation Framework): JavaMail利用JAF来处理MIME编码的邮件附件。MIME的字节流可以被转换成Java对象,或者转换自Java对象。大多数应用都可以不需要直接使用JAF。

  J2EE提供了"编写一次、随处运行"的特性、方便存取数据库的JDBC API、CORBA技术以及能够在Internet应用中保护数据的安全模式等等,同时还提供了对 EJB(Enterprise JavaBeans)、Java Servlets API、JSP(Java Server Pages)以及XML(标准通用标记语言的子集)技术的全面支持。

二、Java企业级开发框架概述

  • EJB(Enterprise Java Bean)

  曾几何时,EJB被人们当做J2EE的核心而顶礼膜拜。
  EJB就是把原来放到客户端实现的代码放到服务器端,并依靠RMI(Remote Method Invocation,是EJB的 技术基础)进行通信。而客户端就单纯负责发送调用请求和显示处理结果。
  在J2EE 中,这个运行在一个独立的服务器上,并封装了业务逻辑的组件就EJB组件。
  回顾EJB出现以前的Java应用开发,大部分开发者直接用JSP页面,再加上少量Java Bean就可以完成整个应用,所有的业务逻辑、数据库访问逻辑都直接写在JSP页面中。系统开发前期,开发者不会意识到有什么问题,但随着开发进行到后期,应用越来越大,开发者需要花费大量时间去解决非常常见的系统级问题,反而无暇顾及真正需要解决的业务逻辑问题。
  对于EJB来说,它提供了一种良好的组件封装,EJB容器负责处理如事务、访问控制等系统级问题,而EJB开发者则集中精力去实现业务逻辑;对页面开发者而言,EJB的存在无须关心,EJB的实现无须关心,他们只要调用EJB的方法即可。
  基于EJB的程序架构总体有一个非常优秀的思想:业务逻辑相关的实现集中在EJB中完成,而EJB容器则负责提供带有重复性质的、系统级的功能,这样EJB组件就可对外提供完整的业务服务。
  但是,由于EJB开发的复杂性,导致许多开发者的批评,以致后来直接催生了spring框架。Spring容器管理的不再是复杂的EJB组件,而是POJO(Plain Old Java Object) Bean。Spring容器取代了原有的EJB容器,以Spring框架为核心的应用无须EJB容器支持,可以直接在Web容器中运行。
  现在SSH(Spring + Struts + Hibernate)是越来越少了,现在比较通用的是SSM(Spring + SpringMVC + Mybatis)。
  在SSH框架中,Spring负责容器管理,对象生命周期的管理以及对象关系的维护。Hibernate负责持久层,它将JDBC做了一个良好的封装,程序员在与数据库进行交互时可以不用书写大量的SQL语句。Struts是在应用层,它负责调用serivce业务逻辑层。
  • Struts

  为了解决这些问题,出现了Struts框架,它是一个完美的MVC实现,它有一个中央控制类(一个Servlet),针对不同的业务,我们需要一个Action类负责页面跳转和后台逻辑运算,一个或几个JSP页面负责数据的输入和输出显示,还有一个Form类负责传递Action和JSP中间的数据。JSP中可以使用Struts框架提供的一组标签,就像使用HTML标签一样简单,但是可以完成非常复杂的逻辑。从此JSP页面中不需要出现一行<%%>包围的Java代码了。
可是所有的运算逻辑都放在Struts的Action里将使得Action类复用度低和逻辑混乱,所以通常人们会把整个Web应用程序分为三层,Struts负责显示层,它调用业务层完成运算逻辑,业务层再调用持久层完成数据库的读写。
  使用JDBC连接来读写数据库,我们最常见的就是打开数据库连接、使用复杂的SQL语句进行读写、关闭连接,获得的数据又需要转换或封装后往外传,这是一个非常烦琐的过程。

  • Hibernate

  这时出现了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框架。

  • Mybatis

  MyBatis是另外一个广泛使用的ORM框架。原本是Apache的一个开源项目iBatis, 后改名为MyBatis 。MyBatis的核心在于管理 POJO 与 SQL 之间的映射关系。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
  Mybatis框架的架构如下图:

Mybatis框架的架构
MyBatis相对于Hibernate,主要优势是可以进行更为细致的SQL优化。
关于MyBatis,详细了解可参考:http://www.mybatis.org/mybatis-3/zh/index.html

  • Spring框架
Spring Framework:
Core support for dependency injection, transaction management, web applications, data access, messaging, testing and more.

  Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(全栈式) 轻量级开源框架。

  • 循证架构(Evidence-Based Architecture)

  Rod Johnson在2002年编著的《Expert one on one J2EE design and development》一书中,对Java EE 系统框架臃肿、低效、脱离现实的种种现状提出了质疑,并积极寻求探索革新之道。以此书为指导思想,他编写了interface21框架,这是一个力图冲破J2EE传统开发的困境,从实际需求出发,着眼于轻便、灵巧,易于开发、测试和部署的轻量级开发框架。
  Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。同年他又推出了一部堪称经典的力作《Expert one-on-one J2EE Development without EJB》,该书在Java世界掀起了轩然大波,不断改变着Java开发者程序设计和开发的思考方式。
  没有最好的架构,只有最合适的架构。循证架构是《Expert One-on-One J2EE Development without EJB》(Rod Johnson,)一书中推崇的架构思路,用俺们的话说就是摸着石头过河,找最适合自己的架构。
  我们曾经在无数的书籍和文章中看到,EJB是J2EE的核心技术之一。而Rod Johnson竟然宣称,绝大多数的J2EE应用根本不需要EJB。
  Rod Johnson引领了一场J2EE领域影响深远的变革。Spring和Hibernate,IoC和AOP,轻量级架构等等。还有更重要的一点,是遵循一切实事求是的“循证架构”的问题解决的方法论哲学。

Rod Johnson认为,应该是基于实践的证据、来自历史项目或亲自试验的经验,而不是任何形式的偶像崇拜或者门户之见。[10]

  “循证哲学”(基于实践的证据、来自历史项目或亲自试验的经验)、“实事求是”的工作方式——这原本就应该是程序员的工作方式。

“认识来源于实践,而又运用于实践”。
——马克思

  人的认识来源于实践,是随着实践的发展而发展的。通过实践得出的认识,只有作用于实践并通过实践的检验,才能够确定认识的正确与否。
  循证架构思想来源于”循证实践“。任何涉及模式,架构模式,编程范式(过程式,面向对象式,函数式,逻辑式,面向服务式)的问题,都是基于解决某个实际业务场景才有其实质存在的意义。

循证实践(Evidence-Based Practise),亦为循证学。本意是"基于证据的实践",其理念始于20世纪末发展起来的循证医学。最初意指医生"将当前所能获得的最佳研究证据与自身的专业技能及患者的价值观整合起来进行治疗"。此后,它便以迅雷不及掩耳之势席卷了整个医疗卫生领域,并不断向邻近学科渗透,形成了循证心理治疗、循证教育学、循证社会学等数十个新的学科领域。

  在程序开发里不同模块之间信息的沟通是通过对象传递完成的,而对象能否顺利传递就是要合理的构建好对象,而管理好对象的构建方式就能管理好对象传递,spring主要就是解决这个问题的。spring提供一个容器,我们在xml文件里,或者通过注解的方式(注解的方式是通过反射机制实现)定义各个对象的依赖关系,由容器完成对象的生命周期的管理(创建,运行,销毁)。
Spring框架建立在IOC和AOP技术之上。

  IOC: Inversion of Control,控制反转,就是由容器控制程序之间的(依赖)关系,而非传统实现中,由程序代码直接操控。 当我们的代码里需要使用某个实例的时候就可以直接从容器里获取。对象的实例化由spring容器负责搞定,所以它被称为控制反转,控制反转的意思就是本来属于java程序里构建对象的功能交由容器接管,依赖注入(DI)就是当程序要使用某个对象时候,容器会把它注入到程序里。Spring IOC有三种注入方式:接口注入、setter注入、构造器注入。
  AOP: Aspect Oriented Programming,面向切面编程,就是把可重用的功能提取出来,然后将这些通用功能在合适的时候织入到应用程序中,比如事务管理、权限控制、日志记录、性能统计等。通过预编译方式和运行期动态代理实现业务逻辑模块之间的隔离,使业务逻辑模块间的耦合度极大化地降低,提高程序可重用性和开发的效率。使用 AOP 后,公共服务 (比 如日志、持久性、事务等)就可以分解成方面并应用到域对象上,同时不会增加域对象的对象模型的复杂性。AOP的工作模式如下图所示:

三、Spring生态系统

  • Spring的整体架构

  Spring框架至今已集成了20多个模块。这些模块主要被分如下图所示的核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块[5]:

Spring整体架构

  • Core Container

  核心部分分为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 and instrumentation

  Aop模块提供了面向切面编程的实现,和AspectJ集成。

  • Messaging

  Messaging是spring4新增加的模块,包含了一部分主要的基于message的应用的实现。

  • Data Access/Integration

  Data access顾名思义,是spring对数据层提供的支持,是功能比较丰富的模块。提供了包括JDBC,事物,ORM,JMS等一系列实现。

  • Web

  Web模块主要提供面向web的一些实现,例如多文件上传,servlet监听器以及spring mvc方面的支持。

  • Test

  Test模块主要是针对spring的各个模块做各种各样的测试,包括单元测试、集成测试等等。

四、Spring JavaConfig

  • Java元编程 (meta-programming)

  一般代码的操作对象是数据。元编程操作的对象是代码。
  元编程一言以蔽之,就是用代码生成(操纵)代码。在运行时创建和修改代码而非编程时,这种程序叫做元程序。而编写这种程序就叫做元编程。元编程是用代码在编译期或运行期生成/改变代码。元编程是现实世界的抽象的利器。
  元编程技术在多种编程语言中都可以使用,但更多的还是被应用于动态语言中,因为动态语言提供了更多的在运行时将代码视为数据进行操纵的能力。
  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等等。
  元编程,是对语言自身再向上一层抽象。

  • JavaConfig简介

  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/).

  • JavaConfig与注解驱动配置( Annotation-Driven Configuration)
后来,当@Annotation出现了,大部分技术、框架就纷纷放弃了XML配置文件,改为使用Annotation来管理配置信息。

Spring有2种常用的配置方式:

  • 基于XML文件的配置
  • 基于@Annotation的配置

  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。

一、用Spring Boot创造一切

  SpringBoot让创建独立的,生产环境的基于Spring的应用更加快捷简易。 大部分Spring Boot Application只要一些极简的配置,即可“一键运行”。
  SpringBoot的特性如下[1]:

  1. 创建独立的Spring applications
  2. 能够使用内嵌的Tomcat, Jetty or Undertow,不需要部署war
  3. 提供定制化的starter poms来简化maven配置(gradle相同)
  4. 追求极致的自动配置Spring
  5. 提供一些生产环境的特性,比如特征指标,健康检查和外部配置。
  6. 零代码生成和零XML配置

  Spring由于其繁琐的配置,一度被人认为“配置地狱”,各种XML、Annotation配置,让人眼花缭乱,而且如果出错了也很难找出原因。而Spring Boot更多的是采用Java Config的方式,对Spring进行配置。
  我们企业级软件的目标是提供稳定健壮的服务,以实现其商业价值。为了满足这些需求,服务开发者需要能够快速构建和迭代新的应用,同时应用的架构是可扩展的,便携式的,富弹性的,可以进行频繁的更新。SpringBoot正式为此而诞生[2]。

二、Spring Boot起源

  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 Boot在Spring生态中的构成

  1、Spring生态顶级项目

    作为当前主流的企业框架Spring,它提供了一整套相关的顶级项目,能让开发者快速的上手实现自己的应用。请看下图“Spring航空母舰”:

  • Spring IO platform:用于系统部署,是可集成的,构建现代化应用的版本平台,具体来说当你使用maven dependency引入spring jar包时它就在工作了。
  • Spring Boot:旨在简化创建产品级的 Spring 应用和服务,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用微服务功能,可以和spring cloud联合部署。
  • Spring Framework:即通常所说的spring 框架,是一个开源的Java/Java EE全功能栈应用程序框架,其它spring项目如spring boot也依赖于此框架。
  • Spring Cloud:微服务工具包,为开发者提供了在分布式系统的配置管理、服务发现、断路器、智能路由、微代理、控制总线等开发工具包。
  • Spring XD:是一种运行时环境(服务器软件,非开发框架),组合spring技术,如spring batch、spring boot、spring data,采集大数据并处理。
  • Spring Data:是一个数据访问及操作的工具包,封装了很多种数据及数据库的访问相关技术,包括:jdbc、Redis、MongoDB、Neo4j等。
  • Spring Batch:批处理框架,或说是批量任务执行管理器,功能包括任务调度、日志记录/跟踪等。
  • Spring Security:是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。
  • Spring Integration:面向企业应用集成(EAI/ESB)的编程框架,支持的通信方式包括HTTP、FTP、TCP/UDP、JMS、RabbitMQ、Email等。
  • Spring Social:一组工具包,一组连接社交服务API,如Twitter、Facebook、LinkedIn、GitHub等,有几十个。
  • Spring AMQP:消息队列操作的工具包,主要是封装了RabbitMQ的操作。
  • Spring HATEOAS:是一个用于支持实现超文本驱动的 REST Web 服务的开发库。
  • Spring Mobile:是Spring MVC的扩展,用来简化手机上的Web应用开发。
  • Spring for Android:是Spring框架的一个扩展,其主要目的在乎简化Android本地应用的开发,提供RestTemplate来访问Rest服务。
  • Spring Web Flow:目标是成为管理Web应用页面流程的最佳方案,将页面跳转流程单独管理,并可配置。
  • Spring LDAP:是一个用于操作LDAP的Java工具包,基于Spring的JdbcTemplate模式,简化LDAP访问。
  • Spring Session:session管理的开发工具包,让你可以把session保存到redis等,进行集群化session管理。
  • Spring Web Services:是基于Spring的Web服务框架,提供SOAP服务开发,允许通过多种方式创建Web服务。
  • Spring Shell:提供交互式的Shell可让你使用简单的基于Spring的编程模型来开发命令,比如Spring Roo命令。
  • Spring Roo:是一种Spring开发的辅助工具,使用命令行操作来生成自动化项目,操作非常类似于Rails。
  • Spring Scala:为Scala语言编程提供的spring框架的封装(新的编程语言,Java平台的Scala于2003年底/2004年初发布)。
  • Spring BlazeDS Integration:一个开发RIA工具包,可以集成Adobe Flex、BlazeDS、Spring以及Java技术创建RIA。
  • Spring Loaded:用于实现java程序和web应用的热部署的开源工具。
  • Spring REST Shell:可以调用Rest服务的命令行工具,敲命令行操作Rest服务。

  2、Spring cloud子项目

目前来说spring主要集中于spring boot(用于开发微服务)和spring cloud相关框架的开发。spring cloud子项目包括:

  • Spring Cloud Config:配置管理开发工具包,可以让你把配置放到远程服务器,目前支持本地存储、Git以及Subversion。
  • Spring Cloud Bus:事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署。
  • Spring Cloud Netflix:针对多种Netflix组件提供的开发工具包,其中包括Eureka、Hystrix、Zuul、Archaius等。
  • Netflix Eureka:云端负载均衡,一个基于 REST 的服务,用于定位服务,以实现云端的负载均衡和中间层服务器的故障转移。
  • Netflix Hystrix:容错管理工具,旨在通过控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
  • Netflix Zuul:边缘服务工具,是提供动态路由,监控,弹性,安全等的边缘服务。
  • Netflix Archaius:配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。
  • Spring Cloud for Cloud Foundry:通过Oauth2协议绑定服务到CloudFoundry,CloudFoundry是VMware推出的开源PaaS云平台。
  • Spring Cloud Sleuth:日志收集工具包,封装了Dapper,Zipkin和HTrace操作。
  • Spring Cloud Data Flow:大数据操作工具,通过命令行方式操作数据流。
  • Spring Cloud Security:安全工具包,为你的应用程序添加安全控制,主要是指OAuth2。
  • Spring Cloud Consul:封装了Consul操作,consul是一个服务发现与配置工具,与Docker容器可以无缝集成。
  • Spring Cloud Zookeeper:操作Zookeeper的工具包,用于使用zookeeper方式的服务注册和发现。
  • Spring Cloud Stream:数据流操作开发包,封装了与Redis,Rabbit、Kafka等发送接收消息。
  • Spring Cloud CLI:基于 Spring Boot CLI,可以让你以命令行方式快速建立云组件。

四、Spring Boot核心组件

五、Spring Boot版本历史

六、Spring Boot学习成本

正因为Spring Boot是与Spring一脉相承的,所以对于广大的Java开发者而言,对于Spring的学习成本几乎为零。
在实践Spring Boot时学习重点,或者说思维方式改变的重点在于:
1)对于REST的理解,这一点尤为重要,需要从设计、开发多个角色达成共识,很多时候都是对于HTTP 1.1协议以及REST的精髓不理解,导致REST被「盲用」而产生一些不好的效果。
2)对于YAML的理解和对于JavaConfig的理解,这两点相对较为简单,本质上是简化了xml文件,并提供等价的配置表述能力。

Spring Boot → 01:概要的更多相关文章

  1. 01 Spring Boot 的简单配置和使用

    Spring Boot 简介 使用 Spring Boot 可以让我们快速创建一个基于 Spring 的项目,而让这个 Spring 项目跑起来我们只需要很少的配置就可以了. 创建 Spring Bo ...

  2. 黑马_13 Spring Boot:01.spring boot 介绍&&02.spring boot 入门

    13 Spring Boot: 01.spring boot 介绍&&02.spring boot 入门 04.spring boot 配置文件 SpringBoot基础 1.1 原有 ...

  3. (01) 什么是Spring Boot

    1.Spring Boot 是spring家族的全新框架: Spring Boot 是简化spring 应用程序的创建和开发过程, 也就是说Spring Boot 能够简化之前采用ssh, ssm框架 ...

  4. Spring Boot概要

    1.Spring Boot使用“习惯优于配置”(项目中存在大量的配置,此外还内置了一个习惯性的配置)的理念,使用户的项目实现快速运行.通过学习Spring Boot中的配置文件application. ...

  5. Spring Boot 学习系列(01)—从0到1,只需两分钟

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 快速构建 如果我们想基于spring mvc 提供一个简单的API查询服务,传统的方式,首先需要我们引入sp ...

  6. spring boot学习01【搭建环境、创建第一个spring boot项目】

    1.给eclipse安装spring boot插件 Eclipse中安装Spring工具套件(STS): Help -> Eclipse Marketplace... 在Search标签或者Po ...

  7. Spring Boot的学习之路(01):缘起

    有人说,Spring Boot的出现,让Java迎来了又一春,它是Java应用开发的颠覆者,彻底改变了Java应用开发的模式. 2017年,SpringBoot闯入我的生活, 也让我迎来了又一春 我开 ...

  8. Spring Boot-初学01 -使用Spring Initializer快速创建Spring Boot项目 -@RestController+spEL -实现简单SpringBoot的Web页面

    1.IDEA:使用 Spring Initializer快速创建项目 IDE都支持使用Spring的项目创建向导快速创建一个Spring Boot项目: 选择我们需要的模块:向导会联网创建Spring ...

  9. 【01】Spring Boot配置文件相关

    1.Spring Boot 获取属性的属性源,优先级从高到低 (1)命令行参数 (2)java:comp/env里的JNDI属性 (3)JVM系统属性 (4)操作系统的环境变量 (5)随机生成的的带r ...

随机推荐

  1. 使用RequestsCookieJar自动保存并传递cookie

    使用python的requests开发爬虫程序的时候,经常需要将之前请求返回的cookie值作为下一个请求的cookie进行调用,比如模拟登录之后的返回的sessionID,就是需要作为后续请求的co ...

  2. svn插件的所有链接

    http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240

  3. CSS元素隐藏方法总结

    display:none; visibility:hidden; opacity:0三者的区别 display:none; 该属性会让元素完全从DOM中消失,浏览器不渲染设置该属性的元素,不占据DOM ...

  4. Windowns API 第24篇 WTSEnumerateSessions 枚举session信息

    函数原型: BOOL WTSEnumerateSessions( HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFO* p ...

  5. Elasticsearch系列(二)--query、filter、aggregations

    本文基于ES6.4版本,我也是出于学习阶段,对学习内容做个记录,如果文中有错误,请指出. 实验数据: index:book type:novel mappings: { "mappings& ...

  6. Django项目:CRM(客户关系管理系统)--64--54PerfectCRM实现CRM客户报名链接

    # kingadmin.py # ————————04PerfectCRM实现King_admin注册功能———————— from crm import models #print("ki ...

  7. webpack处理字体文件

    1. 安装 file-loader npm install file-loader --save-dev 2. 在webpack.config.js中配置 module.exports={ //... ...

  8. npm install时出现error

    今天启动vue前端时,发现依赖没了.于是乎cmd->npm install->更新了部分依赖后,出现error信息,提示更新依赖失败.很奇怪,原来这个项目都是好的,为啥突然更新下来依赖了呢 ...

  9. 嘴巴题3 「BZOJ1412」[ZJOI2009] 狼和羊的故事

    「BZOJ1412」[ZJOI2009] 狼和羊的故事 Description "狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......" Or ...

  10. 如何将本地项目上传到Git 版本库

    1.(先进入项目文件夹)通过命令 git init 把这个目录变成git可以管理的仓库 git init 2.把文件添加到版本库中,使用命令 git add .添加到暂存区里面去,不要忘记后面的小数点 ...