一,Spring Boot 简介
Spring官方网站本身使用Spring框架开发,随着功能以及业务逻辑的日益复杂,应用伴随着大量的XML配置文件以及复杂的Bean依赖关系。随着Spring 3.0的发布,Spring IO团队逐渐开始摆脱XML配置文件,并且在开发过程中大量使用“约定优先配置”(convention over configuration)的思想来摆脱Spring框架中各类繁复纷杂的配置(即时是Java Config)。
Spring Boot正是在这样的一个背景下被抽象出来的开发框架,它本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于Spring框架的应用程序。也就是说,它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。同时它集成了大量常用的第三方库配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot应用中这些第三方库几乎可以零配置的开箱即用(out-of-the-box),大部分的Spring Boot应用都只需要非常少量的配置代码,开发者能够更加专注于业务逻辑。
1.1 Spring Boot 是什么?
首先Spring Boot不是一个框架,它是一种用来轻松创建具有最小或零配置的独立应用程序的方式。这是方法用来开发基于Spring的应用,但只需非常少的配置。它提供了默认的代码和注释配置,快速启动新的Spring项目而不需要太多时间。它利用现有的Spring项目以及第三方项目来开发生产就绪(投入生产)的应用程序。它提供了一组Starter Pom
或gradle构建文件,可以使用它们添加所需的依赖项,并且还便于自动配置。
Spring Boot根据其类路径上的库自动配置所需的类。假设应用程序想要与数据库交互,如果在类路径上有Spring数据库,那么它会自动建立与数据源类的连接。
1.2 Spring Boot的主要目标
为所有Spring开发提供一个基本的,更快,更广泛的入门体验。
开箱即用,但随着需求开始偏离默认值,快速启动。
提供大型项目(例如嵌入式服务器,安全性,度量,运行状况检查,外部化配置)常见的一系列非功能特性。
绝对没有代码生成以及不需要XML配置,完全避免XML配置。
为了避免定义更多的注释配置(它将一些现有的 Spring Framework 注释组合成一个简单的单一注释)
避免编写大量import
语句。
提供一些默认值,以便在短时间内快速启动新项目。
假设要在Spring Framework中开发一个Hello World
应用程序,因为只有一个项目专用于开发Hello World
功能:它就是控制器。其余的是任何使用Spring开发的Web应用程序的通用模板文件。但是如果所有Spring Web应用程序都需要它,为什么都要在每个项目中都必须提供它? 以下是新项目需要Spring Boot的理由了。
当使用默认值时,Spring Boot有自己的看法。如果不指定详细信息,它将使用其自己的默认配置。如果想要持久化,但是没有在POM文件中指定任何东西,那么Spring Boot会将Hibernate带有HSQLDB
数据库的配置作为JPA提供者。
为大型项目(例如嵌入式服务器,安全性,度量,健康检查,外部化配置)提供许多非常常见的非功能特性/解决方案。
二,holo world
web.xml
,applicationContext.xml
,将应用打成war包放入应用服务器(Tomcat, Jetty等)中并运行。如果基于Spring Boot,这一切都将变得简单:以Maven项目为例,首先引入Spring Boot的开发依赖:
org.springframework.boot
spring-boot-starter-parent
1.4.1.RELEASE
org.springframework.boot
spring-boot-starter-web
编写一个类包含处理HTTP请求的方法以及一个main()
函数:
@Controller
@EnableAutoConfiguration
public class SampleController {
@RequestMapping("/")
@ResponseBody
String home() {
return "Hello World!";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleController.class, args);
}
}
启动main函数后,在控制台中可以发现启动了一个Tomcat容器,一个基于Spring MVC的应用也同时启动起来,这时访问[[http://localhost:8080](http://localhost:8080)]([http://localhost:8080](http://localhost:8080))
就可以看到Hello World!
出现在浏览器中了。
在Maven依赖中引入了spring-boot-starter-web
,它包含了Spring Boot预定义的一些Web开发的常用依赖:
spring-web
, spring-webmvc
Spring WebMvc框架tomcat-embed-*
内嵌Tomcat容器jackson
处理json数据spring-*
Spring框架spring-boot-autoconfigure
Spring Boot提供的自动配置功能Java代码中没有任何配置,和传统的Spring应用相比,多了两个我们不认识的符号:
@EnableAutoConfiguration
SpringApplication
它们都是由Spring Boot框架提供。在SpringApplication.run()
方法执行后,Spring Boot的autoconfigure
发现这是一个Web应用(根据类路径上的依赖确定),于是在内嵌的Tomcat容器中启动了一个Spring的应用上下文,并且监听默认的tcp端口8080(默认约定)。同时在Spring Context中根据默认的约定配置了Spring WebMvc:
/
DispatherServlet
匹配的路径(servlet-mapping
中的url-patterns
)是/*
@ComponentScan
路径被默认设置为SampleController
的同名package,也就是该package下的所有@Controller
,@Service
,@Component
,@Repository
都会被实例化后并加入Spring Context中。没有一行配置代码、也没有web.xml
。基于Spring Boot的应用在大多数情况下都不需要我们去显式地声明各类配置,而是将最常用的默认配置作为约定,在不声明的情况下也能适应大多数的开发场景。
3.1 实例:数据库访问
除了最基本的Web框架,另一种非常普遍的开发场景是访问数据库。在传统的Spring应用中,访问数据库我们需要配置:
DataSource
对象,指定数据库url
,username
,password
等信息JdbcTemplate
对象,如果使用Hibernate
,Mybatis
等框架,还需要进一步配置框架信息在Spring Boot中,上述过程会被简化。首先在Maven项目依赖中定义:
org.springframework.boot
spring-boot-starter-web-jdbc
com.h2database
h2
spring-boot-starter-web-jdbc
引入了spring-jdbc
依赖,h2
是一个内存关系型数据库。在引入了这些依赖并启动Spring Boot应用程序后,autoconfigure
发现spring-jdbc
位于类路径中,于是:
h2
,预定义了derby
,sqlite
,mysql
,oracle
,sqlserver
等等),创建一个DataSource
连接池对象,本例中的h2
是内存数据库,无需任何配置,如果是mysql
,oracle
等类型的数据库需要开发者配置相关信息。JdbcTemplate
对象(使用DataSource
初始化)接下来开发者的工作就非常简单了,在业务逻辑中直接引入JdbcTemplate
即可:
@Service
public class MyService {
@Autowired
JdbcTemplate jdbcTemplate;
}
除了spring-jdbc
,Spring Boot还能够支持JPA,以及各种NoSQL数据库——包括MongoDB,Redis,全文索引工具elasticsearch
,solr
等等。
3.2 配置
Spring Boot最大的特色是“约定优先配置”,大量的默认配置对开发者十分的友好。但是在实际的应用开发过程中,默认配置不可能满足所有场景,同时用户也需要配置一些必须的配置项——例如数据库连接信息。Spring Boot的配置系统能够让开发者快速的覆盖默认约定,同时支持Properties配置文件和YAML配置文件两种格式,默认情况下Spring Boot加载类路径上的application.properties
或application.yml
文件,例如:
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
YAML格式更加简洁:
spring:
datasource:
url: jdbc:mysql://localhost/test
username: dbuser
password: dbpass
driver-class: com.mysql.jdbc.Driver
一旦发现这些信息,Spring Boot就会根据它们创建DataSource
对象。另一个常见的配置场景是Web应用服务器:
# Server settings (ServerProperties)
server:
port: 8080
address: 127.0.0.1
sessionTimeout: 30
contextPath: /
# Tomcat specifics
tomcat:
accessLogEnabled: false
protocolHeader: x-forwarded-proto
remoteIpHeader: x-forwarded-for
basedir:
backgroundProcessorDelay: 30 # secs
port
和address
可以修改服务器监听的地址和端口,sessionTimeout
配置session过期时间(再也不用修改web.xml
了,因为它根本不存在)。同时如果在生产环境中使用内嵌Tomcat,当然希望能够配置它的日志、线程池等信息,这些现在都可以通过Spring Boot的属性文件配置,而不再需要再对生产环境中的Tomcat实例进行单独的配置管理了。
从Spring 3.0开始,为了替代繁琐的XML配置,引入了@Enable...
注解对@Configuration
类进行修饰以达到和XML配置相同的效果。想必不少开发者已经使用过类似注解:
@EnableTransactionManagement
开启Spring事务管理,相当于XMl中的
@EnableWebMvc
使用Spring MVC框架的一些默认配置@EnableScheduling
会初始化一个Scheduler用于执行定时任务和异步任务Spring Boot提供的@EnableAutoCongiguration
似乎功能更加强大,一旦加上,上述所有的配置似乎都被包含进来而无需开发者显式声明。它究竟是如何做到的呢,先看看它的定义:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ EnableAutoConfigurationImportSelector.class,
AutoConfigurationPackages.Registrar.class })
public @interface EnableAutoConfiguration {
/**
* Exclude specific auto-configuration classes such that they will never be applied.
*/
Class>[] exclude() default {};
}
EnableAutoConfigurationImportSelector
使用的是spring-core
模块中的SpringFactoriesLoader#loadFactoryNames()
方法,它的作用是在类路径上扫描META-INF/spring.factories
文件中定义的类:
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration
实际上这就是Spring Boot会自动配置的一些对象,例如前面提到的Web框架由EmbeddedServletContainerAutoConfiguration
,DispatcherServletAutoConfiguration
,ServerPropertiesAutoConfiguration
等配置完成,而DataSource
的自动配置则是由DataSourceAutoConfiguration
完成。现在我们以Mongo的配置MongoAutoConfiguration
为例,来探索Spring Boot是如何完成这些配置的:
@Configuration
@ConditionalOnClass(Mongo.class)
@EnableConfigurationProperties(MongoProperties.class)
public class MongoAutoConfiguration {
@Autowired
private MongoProperties properties;
private Mongo mongo;
@PreDestroy
public void close() throws UnknownHostException {
if (this.mongo != null) {
this.mongo.close();
}
}
@Bean
@ConditionalOnMissingBean
public Mongo mongo() throws UnknownHostException {
this.mongo = this.properties.createMongoClient();
return this.mongo;
}
}
首先这是一个Spring的配置@Configuration
,它定义了我们访问Mongo需要的@Bean
,如果这个@Configuration
被Spring Context扫描到,那么Context中自然也就有两个一个Mongo
对象能够直接为开发者所用。
但是注意到其它几个Spring注解:
@ConditionOnClass
表明该@Configuration
仅仅在一定条件下才会被加载,这里的条件是Mongo.class
位于类路径上@EnableConfigurationProperties
将Spring Boot的配置文件(application.properties
)中的spring.data.mongodb.*
属性映射为MongoProperties
并注入到MongoAutoConfiguration
中。@ConditionalOnMissingBean
说明Spring Boot仅仅在当前上下文中不存在Mongo
对象时,才会实例化一个Bean。这个逻辑也体现了Spring Boot的另外一个特性——自定义的Bean优先于框架的默认配置,我们如果显式的在业务代码中定义了一个Mongo
对象,那么Spring Boot就不再创建。接下来看一看MongoProperties
:
@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties {
private String host;
private int port = DBPort.PORT;
private String uri = "mongodb://localhost/test";
private String database;
// ... getters/ setters omitted
}
显然,它就是以spring.data.mongodb
作为前缀的属性,然后通过名字直接映射为对象的属性,同时还包含了一些默认值。如果不配置,那么mongo.uri
就是mongodb://localhost/test
。
从前面的例子可以看出,Spring Boot能够非常快速的做出一些原型应用,但是它同样可以被用于生产环境。为了添加生产环境特性支持,需要在Maven依赖中引入:
org.springframework.boot
spring-boot-starter-actuator
加入actuator
依赖后,应用启动后会创建一些基于Web的Endpoint:
/autoconfig
,用来查看Spring Boot的框架自动配置信息,哪些被自动配置,哪些没有,原因是什么。/beans
,显示应用上下文的Bean列表/dump
,显示线程dump信息/health
,应用健康状况检查/metrics
/shutdown
, 默认没有打开/trace
3.5 Spring Boot 核心和限制
Spring Boot不是编写应用程序的框架,它可以帮助我们以最少的配置或零配置开发和构建,打包和部署应用程序。
它不是应用程序服务器。但是它是提供应用程序服务器功能的嵌入式servlet容器,而不是Spring Boot本身。
类似地,Spring Boot不实现任何企业Java规范,例如JPA或JMS。 例如,Spring Boot不实现JPA,但它通过为JPA实现(例如Hibernate
)自动配置适当的bean
来支持JPA。
最后,Spring Boot不使用任何形式的代码生成来完成它的功能。它是利用Spring 4的条件配置功能,以及Maven和Gradle提供的传递依赖关系解析,以在Spring应用程序上下文中自动配置bean
。
简而言之,Spring Boot它的核心就是Spring。
未来的Spring项目不会有任何XML配置作为它的一部分,一切都将由项目Spring Boot处理。
3.6 Spring Boot 优点和缺点
1)优点:
将现有或传统的Spring Framework项目转换为Spring Boot应用程序是一个非常困难和耗时的过程。它仅适用于全新Spring项目。
Spring Boot是新一代Spring应用的开发框架,它能够快速的进行应用开发,让人忘记传统的繁琐配置,更加专注于业务逻辑。现在Spring官方文档中所有的Guide中的例子都是使用Spring Boot进行构建,这也是一个学习Spring, Spring Boot非常好的地方。如果想进一步深度学习Spring Boot,可以参考:
转载由Ricky创作的Spring Boot——开发新一代Spring Java应用
五,快速入门
主要创建一个简单的Spring Boot 基础项目,并且实现一个简单的Restful Api。
1. 项目构建与解析
版本要求:java 7以上,maven 3.2以上。
1)构建maven项目:
1.1)通过IDEA 中的 Spring Initializr来生成基础项目
1.2)生成后的项目结构主要有:
src/main/java:包含主程序入口
src/main/rerources:配置目录,存放一些配置信息,如应用名,服务端口,数据链接等。
src/test:单元测试
2. 启动服务的方式:
1)直接通过main函数启动
2)在maven 中,之前用到了spring boot 插件,可以用它来启动,比如执行mvn spring - boot:run命令,或直接单击IDEA中对maven插件的工具。
3)通过mvn install 命令将程序编译下,进入到项目的target 目录下,使用java -jar xxx.jar
4)cmd - 进入项目的目录 - 使用 mvn spring-boot:run命令来启动
3. 编写单元测试