java语言简单、安全、支持多线程、高性能和多年javaEE的技术积累,能够快速、安全、高性能地构建互联网项目。
1.Spring 的历史
在Spring框架没有开发出来时,javaEE是以Sun公司所制定EJB(Enterprise Java Bean)作为标准的。在"遥远"的EJB年代,开发一个EJB需要大量的接口和配置文件,直至EJB2.0的年代,开发一个EJB还需要配置两个文件,其结果就是配置的工作量比开发的工作量还要大。其次EJB是运行在EJB容器中的,而sun公司定义的JSP和Servlet却是运行在Web容器中的,于是你可以想象得到,需要使用Web容器去调用EJB容器的服务。这就意味着存在以下的弊端:
2004年 ,Spring成为了现实中JavaEE开发的标准。
2.注解还是XML
Spring1.x:早期(JDK5之前),不支持注解,只能用XML;后期(JDK5之后),一派使用注解,一派使用XML。
Spring2.x:引入了少量的注解,如@Component、@Service等,但是功能还不够强大,因此绝大部分是以使用XML为主,注解为辅。
Spring3.0之后,形成了这样的一个不成文的共识,对于业务类使用注解,例如,对于MVC开发,控制器使用@Controller,业务层使用@Service,持久层使用@Repository;而对于一些公用的Bean,例如,对于数据库(如Redis)、第三方资源等则使用XML进行配置,纸质今时今日这样的配置方式还在企业中广泛地使用着。也许使用注解还是XML是一个长期存在的话题,但是无论如何都有道理。
随着注解的功能增强,尤其是Servlet3.0规范的提出,Web容器可以脱落web.xml的部署,使得Web容器完全可以基于注解开发,对于Spring3.x和Spring4.x的版本注解功能越来越强大,对于XML的依赖越来越少。
到了4.x的版本后甚至可以完全脱离XML,因此在Spring中使用注解开发占据了主流的地位。
与此同时,Pivotal团队在原有Spring的基础上主要通过注解的方式继续简化了Spring框架的开发,它基于Spring框架开发了Spring Boot,所以Spring Boot并非是代替Spring框架,而是让Spring框架更加容易得到快速的使用。
Pivotal 团队2014年推出Spring Boot 1.0,该版本使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。
2018年3月Spring Boot推出了2.0.0 GA版本,该版本是基于Spring5的,并引入其最新的功能,能够有效支持Java9的开发。Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application devlopment)借助JavaEE在企业互联网的强势地位成伟业界领导者,它也是近年来Java开发最令人感到惊喜的项目之一。
随着近年来微服务的流行,越来越多的企业需要快速的开发,而Spring Boot除了以注解为主的开发,还有其他的绑定,例如,对服务器进行了绑定和默认对Spring的最大化配置,所以开发者能够尽快进行开发代码、发布和测试自己的项目。这符合了现今微服务快速开发、测试和部署的需要,于是越来越多的企业选择Spring Boot 作为开发的选型,进而使得Spring Boot更加兴旺起来。本书主要就是论述Spring Boot 这以令人激动的开发工具。
3.Spring Boot的优点
谈到Spring Boo,就让我们先来了解他的优点。依据官方的文档,Spring Boot的优点如下:
这段描述告诉我们,首先Spring Boot是一个基于Spring框架大件起来的应用,其次它会嵌入Tomcat、Jetty或者Undertow等服务器,并且不需要传统的WAR文件进行部署,也就是说大件Spring Boot项目不需要单独下载Tomcat等传统的服务器;同时提供通过Maven(或者Grandle)依赖的starter,这些starter可以直接获取开发所需的相关包,通过这些starter项目就能Java Application的形式运行Spring Boot的项目,而无须其他服务器配置;对于配置,Spring Boot提供Spring框架的最大自动化配置,大量使用自动配置,使得开发者对Spring的配置尽量减少;此外还提供了一些检测、自动检测的功能和外部配置,与此同时没有附加代码和XML的配置要求。
约定优于配置,这是Spring Boot的主导思想。对于Spring Boot而言,大部分情况下存在默认配置,你甚至可以在没有任何定义的情况下使用Spring框架,如果需要自定义也只需要在配置文件配置一些属性便可以,十分便捷。而对于部署这些项目必需的功能,Spring Boot提供starter的依赖,例如,spring-boot-starter-web捆绑了Spring MVC所依赖的包,spring-boot-starter-tomcat绑定了内嵌的Tomcat,这样使得开发者能够尽可能快的搭建开发环境,快速进行开发和部署,这就是Spring Boot的特色。也许作为传统开发者,还未能理解其意义。为了展示Spring Boot的特色,下节将分别展示传统SpringMVC项目和建议的Spring Boot入门实例,并进行比较。
4.传统Spring MVC和Spring Boot的对比
在传统的SpringMVC项目开发中,开发一个简易的SpringMVC项目,需要配置DispatcherServlet,也需要配置Spring IOC的容器。可以选择使用web.xml的配置来实现,当然,如果使用的是Servlet3.1规范,也可以继承由Spring MVC提供的AbstractAnnotationConfigDispatcherServletInitializer来配置Spring MVC项目。这里先给出可以运行的代码示例,即是还不熟悉Spring MVC也没有关系,这里只是为了说明开发比较繁琐而已,后面将详谈Spring MVC的开发原理。
假设已经带入需要的Spring和Spring MVC相关的依赖包到工程中,那么就可以开始配置DispatcherServlet了。例如,代码清单1-1就是通过继承AbstractAnnotationConfigDispatcherServletInitializer的方式来配置Spring MVC的DispatcherServlat的。
代码清单1-1 配置Spring MVC
package com.springboot.springmvc.conf;
import org.springframe.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitialize;
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitialize{
//Spring IOC容器配置
@Override
protected Class>[] getRootConfigClasses(){
//可以返回Spring的Java配置文件数组
return new Class>[]{};
}
//DispatcherServlet的URI的映射关系配置
@Override
protected Class>[] getServletConfigClasses(){
//可以返回Spring的Java配置文件数组
return new Class>[]{WebConfig.class};
}
//DispatcherServlet拦截请求匹配
@Override
protected String[] getServletMappings(){
return new String[]{"*.do"};
}
}
注意代码中引入了一个Java配置文件——WebConfig.java,它的主要作用是配置Spring MVC的核心类DispatcherServlet的上下文,如代码清单1-2所示。
代码清单1-2 配置DispatcherServlet的上下文
package com.springboot.springmvc.conf;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandleAdapter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
//定义Spring MVC扫描包
@ComponentScan(value ="com.*",
includeFilters = {@Filter(type = FilterType.ANNOTATION, value = Collector.class)})
@EnableWebMvc
public class WebConfig {
/**
* 通过注解@Bean初始化视图解析器
*
* @return viewResolver 视图解析器
*/
@Bean(name="internalResourceViewResolver")
public ViewResolver initViewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
/**
* 初始化 RequestMappingHandlerAdapter,并加载HTTP的JSON转换器
*
* @return RequestMappingHandlerAdapter 对象
*/
@Bean(name="requestMappingHandlerAdapter")
public HandlerAdapter initRequestMappingHandlerAdapter(){
//创建 RequestMappingHandlerAdapter 适配器
RequestMappingHandlerAdapter rmhd = new RequestMappingHandlerAdapter();
//HTTP JSON转换器
MappingJackson2HttpMessageConverter jsonConverter = new RequestMappingHandlerAdapter();
//MappingJackson2HttpMessageConverter 接收JSON类型消息的转换
mediaType = MediaType.APPLICATION_JSON_UTF8;
List mediaTypes = new ArrayList();
mediaTypes.add(mediaType);
//加入转换器的支持类型
jsonConverter.setSupportedMediaTypes(mediaTypes);
//给适配器加入JSON转化器
rmhd.getMessageConverters().add(jsonConverter);
return rmhd;
}
}
通过上面的代码,配置完成Spring MVC的开发环境后,才可以开发Spring MVC控制器Controller,这样就可以开发一个简单的控制器(Controller),如代码清单1-3所示。
代码清单1-3 开发Spring MVC控制器
package com.springboot.springmvc.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class TestController{
@RequestMapping("/test")
@ResponseBody
public Map test(){
Map map = new HashMap();
map.put("key","value");
return map;
}
}
这样就完成了一个传统Spring MVC的开发,但是还需要第三方服务器,如Tomcat、WebLogic等服务器去部署的工程。在启动服务器后,再打开浏览器,输入对应的URL,如项目名称为SpringMVC则输入http://localhost:8080/SpringMVC/test.do,就可以得到图1-1的页面。
从上面来看,传统的Spring MVC开发需要配置的内容还是比较多的,而且对设计人员要求较高。开发完成后,开发者还需要找到对应的服务器去运行,如Tomcat或者Jetty等,这样既要进行开发,又要进行配置和部署,工作量还是不少的。
而使用Spring Boot开发后,你就会发现原来一切可以那么简单。不过在入门阶段暂时不需要讨论太多的细节问题,这是未来需要讨论的问题,所以这里只展示它是如何简单而已。首先我们在IDE中创建一个Maven工程,并把其名称定义为Chapter1,这样就可以看到一个Maven配置文件pom.xml,将其内容修改为如代码清单1-4所示。
代码清单1-4 配置Spring Boot依赖环境
4.0.0
springboot
chapter1
war
0.0.1-SNAPSHOT
chapter1 Maven Webapp
http://maven.apache.org
org.springframework.boot
spring-boot-starter-parent
2.0.0.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plagin
从以上代码中可以看到Maven的配置文件引入了多个Spring Boot的starter,Spring Boot会根据Maven配置的starter去寻找对应的依赖,将对应的jar包加载到工程中,而且它还会把绑定的服务器也加载到工程中,这些都不需要你在进行处理。正如Spring Boot承诺的那样,绑定服务器,并且实现Spring的尽可能的配置,采用约定优于配置的原则。这里我们只需要开发一个类就可以运行Spring Boot的应用了,为此新建类——Chapter1Main,如代码清单1-5所示。
代码清单1-5 开发Spring Boot应用
package com.springboot.chapter1.main;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@SpringBootApplication
@Controller
//启用Spring Boot自动装配
@EnableAutoConfiguration
public class Chapter1Main {
public static void main(String[] args) {
SpringApplication.run(Chapter1Main.class, args);
}
@RequestMapping("/test")
@ResponseBody
public Map test() {
Map map = new HashMap<>();
map.put("key1", "value1");
return map;
}
}
这个入门实例已经完结了。现在完全可以使用Java Application的形式去运行类Chapter1Main。运行之后,从日志中可以看到,Tomcat已经启动,并且将我们开发的Chapter1Main作为Spring MVC的控制器加载进来了,也将对应的路径(/test)映射到开发的test方法上。接下来就可以进行测试了。打开浏览器,在地址栏输入http:localhost:8080/test,可以看到如图1-2所示的结果。
与传统的Spring MVC不一样,Spring Boot允许直接运行开发,这就是它的优势。在传统所需要配置的地方,Spring Boot都进行约定,也就是你可以直接以Spring Boot约定的方式进行开发和运行项目。当需要修改配置的时候,它也提供了一些快速配置的约定,犹如他所承诺的那样,尽可能地配置好Spring项目和绑定对应的服务器,使得开发人员的配置更少,更加直接地开发项目。对于那些微服务而言,更喜欢的就是这样能够快速搭建环境的项目,而Spring Boot提供了这种可能性,同时Spring Boot还提供了监控的功能,随着云技术的到来,微服务成了市场的热点,于是代表Java微服务时代的Spring Boot微服务开发的时代已经到来,结合Spring Cloud后它还能很方便地构建分布式系统开发,满足大部分无能力单独开发分布式架构的企业所需,所以这无疑是激动人心的技术。后面的章节让我们就走进Spring Boot开发的森林中。