写点什么

使用 Spring Boot 快速构建应用

  • 2014-01-20
  • 本文字数:3794 字

    阅读完需:约 12 分钟

随着 Spring 4 新版本的发布 Spring Boot 这个新的子项目得到了广泛的关注,因为不管是 Spring 4 官方发布的新闻稿还是针对首席架构师Adrian Colyer 的专访,都对这个子项目所带来的生产率提升赞誉有加。

Spring Boot 充分利用了 JavaConfig 的配置模式以及“约定优于配置”的理念,能够极大的简化基于 Spring MVC 的 Web 应用和 REST 服务开发。

Spring 4 倡导微服务的架构,针对这一理念,近来在微博上也有一些有价值的讨论,如这里这里。微服务架构倡导将功能拆分到离散的服务中,独立地进行部署,Spring Boot 能够很方便地将应用打包成独立可运行的 JAR 包,因此在开发模式上很契合这一理念。目前,Spring Boot 依然是 0.5.0 的里程碑版本,因此相关的文档尚不完善,本文将会以一个简单的样例来介绍基于这个项目的开发过程。

要 Spring Boot 进行功能开发,需要使用 Gradle 或者 Maven 作为构建工具。在本例中,我们会使用 Eclipse 和 Maven 插件进行开发。要使用 Spring Boot,首先创建一个 Maven 工程,并修改 Maven 主要的配置文件 pom.xml,如下所示:

复制代码
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>0.5.0.M7</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring3</artifactId>
</dependency>
</dependencies>
<properties>
<start-class>com.levin.Application</start-class>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestone</id>
<url>http://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestone</id>
<url>http://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

在上面的配置中,需要将工程的 parent 设置为 spring-boot-starter-parent,并添加对 spring-boot-starter-web 的依赖,这样我们就无需设置各个依赖项及其版本信息了。并且在构建中要声明使用 spring-boot-maven-plugin 这个插件,它会对 Maven 打包形成的 JAR 进行二次修改,最终产生符合我们要求的内容结构。

在我们的应用中将要发布一个 REST 服务,显示一个基本的用户信息,首先定义一个简单的模型类:

复制代码
package com.levin;
public class Person {
private String name;
private String email;
public Person(String name, String email) {
this.name = name;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

接下来,我们需要声明一个 Spring MVC 的 Controller,响应对实体的请求:

复制代码
@Controller
public class ShowPersonController {
@RequestMapping("/showPerson")
public @ResponseBody Person showPerson() {
return new Person("levinzhang","levinzhang1981@gmail.com");
}
}

这个类与我们在使用 Spring MVC 定义 Controller 时并无任何差别。接下来,我们需要声明一个主类启动这个应用程序:

复制代码
@ComponentScan
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

这个类的 main 方法中使用了 SpringApplication 帮助类,并以 Application 这个类作为配置来启动 Spring 的应用上下文。在这个类中使用了 ComponentScan 以及 EnableAutoConfiguration 注解,其中 ComponentScan 注解会告知 Spring 扫描指定的包来初始化 Spring Bean,这能够确保我们声明的 Bean 能够被发现。EnableAutoConfiguration 将会启动自动配置模式,在我们的配置中会将对 Tomcat 的依赖级联进来,因此在应用启动时将会自动启动一个嵌入式的 Tomcat,因为在样例中使用了 Spring MVC,所以也会自动注册所需的 DispatcherServlet,这都不需要类似 web.xml 这样的配置。

在 Eclipse 中要运行这个应用的话,可以直接以 Java Application 的形式来运行这个 main 函数,此时会启动应用,我们在浏览器中可以看到如下的运行效果,这就是我们想要的 REST 服务:

在开发调试完成之后,可以将应用打成 JAR 包的形式,在 Eclipse 中可以直接使用 Maven 插件的 package 命令,最终会形成一个可运行的 JAR 包。我们使用 java –jar 命令就可以运行这个 JAR 包了。所呈现出的效果与在调试期是一样的。现在看一下这个 JAR 包解压后的目录结构:

这个 JAR 包与传统 JAR 包的不同之处在于里面有一个名为 lib 的目录,在这个目录中包含了这个简单应用所依赖的其他 JAR 包,其中也包含内置的嵌入式 Tomcat,正是使用它,才能发布服务和访问 Web 资源。除了我们编写的源码所编译形成的 CLASS 以外,在 org 目录下还有许多 Spring 所提供的 CLASS,正是依赖这些 CLASS,才能够加载位于 lib 目录下 JAR 中的类。这样的加载机制与在 OSGi bundle 中声明 Bundle-Classpath 很类似,不过在 OSGi 中会由容器来负责加载指定路径下的类。这大致阐述了这样一个 JAR 包能够发布服务的原因。

如果我们想要使用 HTML、JSP 等 Web 资源的话,在 Controller 中直接返回对应的视图就可以了。

如果我们想要将这个 JAR 包转换成可以在 Servlet 容器中部署的 WAR 的话,就不能依赖于 Application 的 main 函数了,而是要以类似于 web.xml 文件配置的方式来启动 Spring 应用上下文,此时我们需要声明这样一个类:

复制代码
public class HelloWebXml extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}

这个类的作用与在 web.xml 中配置负责初始化 Spring 应用上下文的监听器作用类似,只不过在这里不需要编写额外的 XML 文件了。

如果要将最终的打包形式改为 WAR 的话,还需要对 pom.xml 文件进行修改,除了需要将 packaging 的值修改为 war 以外,还需要对依赖进行适当的配置(这一部分在 Spring Boot 的样例和文档中均未提及,提醒大家注意):

复制代码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>

在这里需要移除对嵌入式 Tomcat 的依赖,这样打出的 WAR 包中,在 lib 目录下才不会包含 Tomcat 相关的 JAR 包,否则将会出现启动错误。另外,在移除对 Tomcat 的依赖后,为了保证编译正确,还需要添加对 servlet-api 的依赖,因此添加如下的配置:

复制代码
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.42</version>
<scope>provided</scope>
</dependency>

在这里将 scope 属性设置为 provided,这样在最终形成的 WAR 中不会包含这个 JAR 包,因为 Tomcat 或 Jetty 等服务器在运行时将会提供相关的 API 类。此时,执行 mvn package 命令就会得到一个 WAR 文件,我们可以直接将其放到 Tomcat 下运行(需要 7.0.42 版本以上)。

以上介绍了基于 Spring Boot 开发应用的过程,目前它的文档尚不完善,但是在 GitHub 上有不少的样例,包括与 Spring Data 集成访问数据库(关系型以及非关系型)、安全、WebSocket 等,读者感兴趣可以下载运行,需要注意的是有些样例中使用的是 0.5.0.M6 版本,这个版本有问题,运行时会出错,建议手动修改为 0.5.0.M7 或快照版本。

基于以上的介绍,希望读者能够对 Spring Boot 这个新项目有所了解。它简化了 JAR 包管理和相关基础设施环境的配置,能够帮助我们快速开发 Web 应用或构建 REST 服务,希望它能够尽快完善成熟,更多地用于实践,提升开发效率。

参考资料

http://projects.spring.io/spring-boot/

http://projects.spring.io/spring-boot/docs/README.html

http://spring.io/guides/gs/spring-boot/

http://spring.io/guides/gs/actuator-service/

http://spring.io/guides/gs/convert-jar-to-war/

2014-01-20 23:2339768

评论

发布
暂无评论
发现更多内容

5招教你实现多线程场景下的线程安全

华为云开发者联盟

Java 线程 多线程 线程安全

Asop 之 消息处理机制

Qunar技术沙龙

android Linux 消息队列 安卓 epoll

聊聊 PC 端自动化最佳方案 - WinAppDriver

星安果

Python 自动化 WinAppDriver

ipfs矿机挖币哪家最好?ipfs矿机公司实力排行如何?

ipfs矿机挖币哪家最好 ipfs矿机公司实力排行如何

高防服务器大数据时代下的最佳应用途径

九河云安全

想聊天?自己搭建个聊天机器人吧!

百度开发者中心

人工智能 最佳实践 方法论 飞桨 语言 & 开发

云服务器市场改变了行业市场的发展规模

九河云安全

7金5银,中国跳水梦之队背后的"黑科技"是什么?

百度大脑

人工智能 黑科技 跳水队

舍弃Kong和Nginx,Apache APISIX 在趣链科技 BaaS 平台的落地实践

API7.ai 技术团队

nginx 开源 网关 kong APISIX

程序员投入时间和精力实现财富增长之道,这可能会伴随你程序员整个生涯(请不要连续点赞)

孙叫兽

程序员 赚钱 教程 引航计划 签约计划第二季

企业在运营过程中需要解决的五项网络安全项目

九河云安全

波场DAPP钱包开发|波场DAPP特点

Geek_23f0c3

钱包系统开发 DAPP智能合约交易系统开发 波场DAPP 波场钱包

「独立思考」的背后是一个残酷的世界

非著名程序员

提升认知 个人提升 独立思考 8月日更

趁着课余时间学点Python(十)面向对象的理解(前奏)

ベ布小禅

8月日更

YYDS《剑指Offer》再续新篇,百万程序员人手一册

博文视点Broadview

TCP 三次握手

W🌥

计算机网络 TCP/IP 8月日更

Redis扩展数据类型详解

码农参上

redis 8月日更

高防云服务器服务器的价值会随着时间而扩展,从"成本效率"扩展到"新服务和技术"

九河云安全

数据库的简述与常用操作指南

行者AI

数据库

知乎李大海对话阿里云贾扬清:透视AI应用难题与未来趋势

阿里云大数据AI技术

连续霸榜丨EasyDL到底有多强?

百度大脑

人工智能 EasyDL

绝了!阿里甩出“源码阅读指南”,原来源码才是最经典的学习范例

Java 编程 架构 面试 程序人生

一文带你了解大厂亿级并发下高性能服务器是如何实现的!

Linux服务器开发

事件驱动 多进程 Linux服务器开发 IO多路复用 高性能服务器

图谱可视化|手把手教你采集明星人物关系并进行图谱展示

Python研究者

知识图谱 8月日更

贡献者,是衡量开源项目的金指标

API7.ai 技术团队

开源 网关 APISIX

使用FL studio中文版进行音乐合并和剪切

懒得勤快

企业数字化转型第一步,云服务器的部署以及搭建

九河云安全

跟我读论文丨ACL2021 NER BERT化隐马尔可夫模型用于多源弱监督命名实体识别

华为云开发者联盟

BERT 弱监督 隐马尔可夫 CHMM HMM模型

对象存储手把手教四 | Bucket 生命周期管理

QingStor分布式存储

对象存储 分布式存储 生命周期 数据管理

Karmada: 云原生多云容器编排平台

华为云原生团队

开源 容器 k8s多集群管理 多云管理平台 多云

大数据集群跨多版本升级、业务0中断,只因背后有TA

华为云开发者联盟

大数据 FusionInsight

使用Spring Boot快速构建应用_Java_张卫滨_InfoQ精选文章